Warbase Filters

Filter things out of the war base

当前为 2017-07-04 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Warbase Filters
// @namespace    somenamespace
// @version      0.3
// @description  Filter things out of the war base
// @author       tos
// @include        *.torn.com/factions.php?step=your
// @grant        GM_addStyle
// ==/UserScript==

animation_enabled = true
animation_duration = 5 //minutes

GM_addStyle(
  '#wars_expanded .descriptions-new {'+
  'display:block;'+
  'margin: 0;'+
  'float: left;'+
  'background-color: transparent;'+
  'border-radius: 0;'+
  'box-shadow: none;'+
  'height: auto;'+
  'width: 100%;}'+
  
  '#warbase_filters {'+
  'padding: 5px;}'+
  
  '#warbase_filters .wb_content_left {'+
  'display: inline-block;'+
  'width: 50%;'+
  'vertical-align: top;}'+
  
  '#warbase_filters .wb_content_right {'+
  'display: inline-block;'+
  'width: 50%;'+
  'vertical-align: top;}'+
  
  '#warbase_filters .wbTotals_col_left{'+
  'display: inline-block;'+
  'font-size: 110%;'+
  'font-weight: bold;'+
  'width: auto;}'+
  
  '#warbase_filters .wbTotals_col_right{'+
  'display: inline-block;'+
  'font-size: 110%;'+
  'width: auto;}'+
  
  '#warbase_filters span{'+
  'display: block;'+
  'padding: 1px 10px;}'+
  
  '#warbase_filters input[type="checkbox"] {'+
  'margin-right: 3px;}'+
  
  '#warbase_filters input[type="number"] {'+
  'background: transparent;'+
  'border-bottom: 2px solid black;'+
  'text-align: center;'+
  'width: 50px;}'+
  
  '#warbase_filters .wbTotals_title{'+
  'padding: 1px 0px 1px 10px;}'+
  
  '#warbase_filters .wbTotals {'+
  'padding: 1px 0px;'+
  'text-align: right;'+
  'font-weight: normal;}'+
  
  '.f-chain {border-radius: 14px}'+
  
  '@keyframes chainIconFade {'+
  'from {background-color: #b2b2b2;}'+
  'to {background-color: #f2f2f2;}}'+
  
  '.animation_colorfade {'+
  'animation-name: chainIconFade;'+
  'animation-duration: '+ animation_duration * 60 +'s;}'+
  
  '#warbase_results {'+
  'display: none;}'+
  
  '#warbase_results .wbResults_placeholder {'+
  'font-weight: bold;'+
  'padding: 10px;}'+
  
  '#wars_expanded {'+
  'margin-bottom:10px;}'
);

let filters = JSON.parse(localStorage.getItem('torn_warbase_filters')) || {}
if(!filters.hasOwnProperty('fed')) filters.fed = false
if(!filters.hasOwnProperty('traveling')) filters.traveling = false
if(!filters.hasOwnProperty('jail_hosp')) filters.jail_hosp = false
if(!filters.hasOwnProperty('jail_hosp_time')) filters.jail_hosp_time = 0
if(!filters.hasOwnProperty('level')) filters.level = false
if(!filters.hasOwnProperty('level_min')) filters.level_min = 0
if(!filters.hasOwnProperty('level_max')) filters.level_max = 100
if(!filters.hasOwnProperty('extended')) filters.extended = false

let faction_nodes = {}
let faction_totals = {}

const count_enemies = (obj) => {
  let enemy_totals = {total:0, ok:0, hidden:0}
  for (const factionID of Object.keys(obj)) {
    enemy_totals.total += faction_totals[factionID].total
    enemy_totals.ok += faction_totals[factionID].ok
    enemy_totals.hidden += faction_totals[factionID].hidden
  }
  return enemy_totals
}

const run_filters = (node) => {
  const factionID = node.querySelector('.t-blue').href.split('&')[1].replace('=', '')
  let target_TOTALS = {total: 0, ok: 0, hidden: 0}
  faction_totals[factionID] = {}
  for (const enemy_LI of node.querySelector('.member-list').children) {
    target_TOTALS.total += 1
    const status = enemy_LI.querySelector('.status').firstElementChild.innerText
    //const bountied = enemy_LI.querySelector('#icon13') || false
    //if(bountied) enemy_LI.style.backgroundColor ='#F0D9D2';
    let hosp_time = 0
    if (enemy_LI.querySelector('#icon15')) {
      const time_string = enemy_LI.querySelector('#icon15').title.split('\'>')[1].split('</')[0]
      hosp_time = parseInt(time_string.split(':')[0]) * 3600 + parseInt(time_string.split(':')[1]) * 60 + parseInt(time_string.split(':')[2])
    }
    let jail_time = 0
    if (enemy_LI.querySelector('#icon16')) {
      const time_string = enemy_LI.querySelector('#icon16').title.split('\'>')[1].split('</')[0]
      jail_time = parseInt(time_string.split(':')[0]) * 3600 + parseInt(time_string.split(':')[1]) * 60 + parseInt(time_string.split(':')[2])
    }
    const level = parseInt(enemy_LI.querySelector('.lvl .t-hide').nextSibling.textContent)
    
    if (status === 'Okay') target_TOTALS.ok +=1
    if (filters.fed && status === 'Federal') enemy_LI.style.display = 'none' 
    else if (filters.traveling && status === 'Traveling') enemy_LI.style.display = 'none' 
    else if (filters.jail_hosp && (filters.jail_hosp_time * 60 < jail_time || filters.jail_hosp_time * 60 < hosp_time)) enemy_LI.style.display = 'none'
    else if (filters.level && (filters.level_min > level || filters.level_max < level)) enemy_LI.style.display = 'none'
    else enemy_LI.style.display = 'list-item'
    
    if (enemy_LI.style.display === 'none') target_TOTALS.hidden += 1
  }
  
  faction_totals[factionID].total = target_TOTALS.total
  faction_totals[factionID].ok = target_TOTALS.ok
  faction_totals[factionID].hidden = target_TOTALS.hidden
  
  const warbase_totals = count_enemies(faction_totals)
  const wbTotals = document.querySelectorAll('.wbTotals')
  for (const totals_span of wbTotals) {
    const totals_controls = totals_span.className.split('wb_')[1]
    totals_span.innerText = warbase_totals[totals_controls]
  }
}

const observer = new MutationObserver((mutations) => {
  for (const mutation of mutations) {
    for (const node of mutation.addedNodes) {
      if (node.className && node.className === 'faction-respect-wars-wp') {
        const war_list = node.querySelector('.f-war-list')
//Build Filter DIV
        const filter_DIV = document.createElement('DIV')
        filter_DIV.innerHTML =
          '<div>'+
          '<div class="title-black m-top10 top-round">War Base Filters</div>'+
            '<div class="cont-gray map-wrap bottom-round " id="warbase_filters">'+
              '<div class="wb_content_left">'+
                '<span><input type="checkbox" class="wbFilter wb_fed">Federal</span>'+
                '<span><input type="checkbox" class="wbFilter wb_traveling">Traveling</span>'+
                '<span><input type="checkbox" class="wbFilter wb_jail_hosp">In Jail/Hosp for <input type="number" class="wbFilter wb_jail_hosp_time">+ minutes</span>'+
                '<span><input type="checkbox" class="wbFilter wb_level">Level<input type="number" class="wbFilter wb_level_min">to<input type="number" class="wbFilter wb_level_max"></span>'+
              '</div>'+
              '<div class="wb_content_right">'+
                '<div class="wbTotals_col_left">'+
                  '<span class="wbTotals_title">Warbase Total:&nbsp;</span>'+
                  '<span class="wbTotals_title">Enemies Okay:&nbsp;</span>'+
                  '<span class="wbTotals_title">Enemies Hidden:&nbsp;</span>'+
                '</div>'+
                '<div class="wbTotals_col_left">'+
                  '<span class="wbTotals wb_total"></span>'+
                  '<span class="wbTotals wb_ok"></span>'+
                  '<span class="wbTotals wb_hidden"></span>'+
                '</div>'+
                '<span><input type="checkbox" class="wbFilter wb_extended">Extended Warbase</span>'+
              '</div>'+
            '</div>'+
          '</div>'
        node.insertBefore(filter_DIV, war_list)
        const filter_inputs = document.querySelectorAll('.wbFilter')
        for (const wbFilter of filter_inputs) {
          const filter_controls = wbFilter.className.split('wb_')[1]
          switch (wbFilter.type) {
            case 'checkbox':
              wbFilter.checked = filters[filter_controls]
              wbFilter.addEventListener('change', (event) => {
                filters[filter_controls] = event.target.checked
                localStorage.setItem('torn_warbase_filters', JSON.stringify(filters))
                if (document.querySelector('#faction-main .descriptions')) {
                  run_filters(document.querySelector('#faction-main .descriptions'))
                }
                if (document.querySelector('#wars_expanded')) {
                  for (const listItem of document.querySelector('#wars_expanded').children) {
                    if (listItem.className === 'descriptions-new') {
                      run_filters(listItem)
                    }
                  }
                }
                if (event.target.className === 'wbFilter wb_extended') {
                  if (event.target.checked) document.querySelector('#warbase_results').style.display = 'block'
                  else document.querySelector('#warbase_results').style.display = 'none'
                }
              })
              break
            case 'number':
              wbFilter.value = filters[filter_controls]
              wbFilter.addEventListener('change', (event) => {
                filters[filter_controls] = event.target.value
                localStorage.setItem('torn_warbase_filters', JSON.stringify(filters))
                if (document.querySelector('#faction-main .descriptions')) {
                  run_filters(document.querySelector('#faction-main .descriptions'))
                }
                if (document.querySelector('#wars_expanded')) {
                  for (const listItem of document.querySelector('#wars_expanded').children) {
                    if (listItem.className === 'descriptions-new') {
                      run_filters(listItem)
                    }
                  }
                }
              })
              break
            default:
              break
          }
        }
        const mainWrap = document.querySelector('#faction-main')
        const territoryWrap = document.querySelector('#faction-wars-wp')
        const warlist_DIV = document.createElement('DIV')
        warlist_DIV.id = 'warbase_results'
        warlist_DIV.innerHTML =
          '<div class="title-black m-top10 top-round">War Base Extended</div>'+
          '<div class="cont-gray map-wrap bottom-round">'+
            '<div class="wbResults_placeholder">Updates on faction tab clicks...</div>'+
            '<ul id="wars_expanded" class="f-war-list war-old">'+
              '<li class="clear"></li>'+
            '</ul>'+
          '</div>'
        mainWrap.insertBefore(warlist_DIV, territoryWrap)
        if (filters.extended) {
          warlist_DIV.style.display = 'block'
        }
      }
//Observing for tabs opening--------------------------------------------------------------------------------------------------------------------------------
      if (node.className && node.className === 'descriptions') {
        if (node.querySelector('.member-list')) {
          const factionID = node.querySelector('.t-blue').href.split('&')[1].replace('=', '')
          
          if (animation_enabled) {
            const chain_icon = node.parentElement.querySelector('.act .f-chain')
            if (chain_icon.className.includes('animation_colorfade')) {
            	chain_icon.classList.remove('animation_colorfade')
            	void chain_icon.offsetWidth
            }
            chain_icon.classList.add('animation_colorfade')
            chain_icon.addEventListener("animationend", (anim) => anim.target.classList.remove('animation_colorfade'))
          }
          
          run_filters(node)
          
          //clone node
          const wars_expanded = document.querySelector('#wars_expanded')
          faction_nodes[factionID] = node.cloneNode(true)
          faction_nodes[factionID].id = factionID
          faction_nodes[factionID].className = 'descriptions-new'
          if (!document.querySelector('#'+factionID)) {
            wars_expanded.parentElement.querySelector('.wbResults_placeholder').style.display = 'none'
            wars_expanded.insertBefore(faction_nodes[factionID], wars_expanded.lastChild)
          }
          else {
            wars_expanded.replaceChild(faction_nodes[factionID], document.querySelector('#'+factionID))
          }
        }
      }
    }
  }
});

const wrapper = document.querySelector('#faction-main')
observer.observe(wrapper, { subtree: true, childList: true })