Filter things out of the war base
当前为
// ==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: </span>'+
'<span class="wbTotals_title">Enemies Okay: </span>'+
'<span class="wbTotals_title">Enemies Hidden: </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 })