NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name ThirtyNinthWBE // @namespace 39th.wBE // @author Vinkuun [1791283] (edited by UcanTeneke [10611]) // @description No description :) // @include *.torn.com/factions.php?step=your* // @include *.torn.com/profiles.php?XID=* // @include *.torn.com/loader2.php?sid=getInAttack* // @version 2.5.16 // @require http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js // @grant GM_addStyle // ==/UserScript== 'use strict'; this.$ = this.jQuery = jQuery.noConflict(true); // global CSS GM_addStyle( '#vinkuun-extendedWarBasePanel { line-height: 2em }' + '#vinkuun-extendedWarBasePanel label { background-color: rgba(200, 195, 195, 1); padding: 2px; border: 1px solid #fff; border-radius: 5px }' + '#vinkuun-extendedWarBasePanel input { margin-right: 5px; vertical-align: text-bottom }' + '#vinkuun-extendedWarBasePanel input[type="number"] { vertical-align: baseline; line-height: 1.3em }' + '#vinkuun-extendedWarBasePanel { padding: 4px; }' ); var $MAIN = $('#faction-main'); // ============================================================================ // --- FEATURE: War Base Layout // ============================================================================ function sortByRespect(parent, childSelector, keySelector, ascdesc) { var items = parent.children(childSelector).sort(function(a, b) { var vA = parseFloat($(keySelector, a).attr("title").replace(/[^0-9\.]+/g, "")); var vB = parseFloat($(keySelector, b).attr("title").replace(/[^0-9\.]+/g, "")); if (ascdesc == "desc") { return (vA > vB) ? -1 : (vA < vB) ? 1 : 0; } else { return (vA < vB) ? -1 : (vA > vB) ? 1 : 0; } }); parent.append(items); } var originalSort; function enableWarBaseLayout() { var fragment = document.createDocumentFragment(); $('.f-war-list .desc-wrap').each(function() { var row = document.createElement('li'); row.classList.add('descriptions'); $(this.children).each(function() { row.appendChild(this); }); fragment.appendChild(row); }); originalSort = document.createElement('div'); originalSort.appendChild( fragment.cloneNode(true) ); $('.f-war-list li:not(.clear)').remove(); $('.f-war-list').prepend(fragment); $('.f-msg').css('margin-bottom', '10px'); GM_addStyle( '.f-war-list .descriptions { margin-top: 10px !important; border-radius: 5px !important }' + '.f-war-list .descriptions .status-desc { border-radius: 5px 5px 0 0 !important }' ); } function sortLayout(sortby) { var sortthis = originalSort.cloneNode(true); sortthis = $(sortthis); if (sortby == "respectdesc") { sortByRespect(sortthis, "li", ".progress-cont.pos", "desc"); } else if (sortby == "respectasc") { sortByRespect(sortthis, "li", ".progress-cont.pos", "asc"); } $('.f-war-list.war-old li:not(.clear)').remove(); $('.f-war-list.war-old').prepend(sortthis); } // ============================================================================ // --- FEATURE: War base filter // ============================================================================ var warBaseFilter; var $filterStatusElement; /** * Adds the filter panel to the war base extended main panel * @param {jQuery-Object} $panel Main panel */ function addWarBaseFilter($panel) { var $warList = $('.f-war-list'); var $statusElement = $('<p>', {text: 'The war base is currently hidden. Click the bar above to show it.', style: 'text-align: center; margin-top: 4px; font-weight: bold'}).hide(); $('.f-msg') .css('cursor', 'pointer') .on('click', function() { if (shouldHideWarBase()) { localStorage.vinkuunHideWarBase = false; $warList.show(); $statusElement.hide(); } else { localStorage.vinkuunHideWarBase = true; $warList.hide(); $statusElement.show(); }}) .attr('title', 'Click to show/hide the war base') .after($statusElement); if (shouldHideWarBase()) { $warList.hide(); $statusElement.show(); } // load saved war base filter settings warBaseFilter = JSON.parse(localStorage.vinkuunWarBaseFilter || '{}'); warBaseFilter.status = warBaseFilter.status || {}; $filterStatusElement = $('<span>', {text: 0}); addFilterPanel($panel); applyFilter(); } // returns true if the layout is enabled, false if not function shouldHideWarBase() { return JSON.parse(localStorage.vinkuunHideWarBase || 'false'); } /** * Applys the filter to the war base * * @param {jquery-Object} $list * @param {Object} filter */ function applyFilter() { var $list = $MAIN.find('ul.f-war-list'); // show all members $list.find('li').show(); var countFiltered = 0; var items; if (warBaseFilter.status.okay) { items = $list.find('span:contains("Okay")'); countFiltered += items.length; items.parent().parent().hide(); } if (warBaseFilter.status.traveling) { items = $list.find('span:contains("Traveling")'); countFiltered += items.length; items.parent().parent().hide(); } if (warBaseFilter.status.jail) { items = $list.find('span:contains("Jail")'); countFiltered += items.length; items.parent().parent().hide(); } if (warBaseFilter.status.federal) { items = $list.find('span:contains("Federal")'); countFiltered += items.length; items.parent().parent().hide(); } if (warBaseFilter.status.hospital) { $list.find('span:contains("Hospital")').each(function() { var $this = $(this); var $li = $this.parent().parent(); var hospitalTimeLeft = remainingHospitalTime($li.find('.member-icons #icon15').attr('title')); if (hospitalTimeLeft > warBaseFilter.status.hospital) { countFiltered++; $li.hide(); } }); } if (warBaseFilter.levelfilterMin && warBaseFilter.levelfilterMax) { $list.find('.member-list li .lvl').each(function() { var $this = $(this); var $li = $this.parent(); var levelN = $this.text().replace(/\D/g,''); if (levelN < warBaseFilter.levelfilterMin || levelN > warBaseFilter.levelfilterMax) { if ($li.is(':visible')) { countFiltered++; } $li.hide(); } }); } if (warBaseFilter.status.online === false) { $list.find('.member-list li li#icon1').each(function() { var $this = $(this); var $li = $this.parent().parent().parent(); var isOnline = $this.attr('title').replace('<b>','').replace('</b>','') == 'Online' ? true : false; if (isOnline) { if ($li.is(':visible')) { countFiltered++; } $li.hide(); } }); } if (warBaseFilter.status.idle === false) { $list.find('.member-list li li#icon62').each(function() { var $this = $(this); var $li = $this.parent().parent().parent(); var isIdle = $this.attr('title').replace('<b>','').replace('</b>','') == 'Idle' ? true : false; if (isIdle) { if ($li.is(':visible')) { countFiltered++; } $li.hide(); } }); } if (warBaseFilter.status.offline === false) { $list.find('.member-list li li#icon2').each(function() { var $this = $(this); var $li = $this.parent().parent().parent(); var isOffline = $this.attr('title').replace('<b>','').replace('</b>','') == 'Offline' ? true : false; if (isOffline) { if ($li.is(':visible')) { countFiltered++; } $li.hide(); } }); } // update the number of hidden members $filterStatusElement.text(countFiltered); } /** * Panel to configure the filter - will be added to the main panel */ function addFilterPanel($panel) { var enemiesInWarBase = $('ul.f-war-list .act-cont').length; $panel.append('<p>There are ' + enemiesInWarBase + ' enemies in the war base.</p>'); $panel.append("Hide enemies who are "); // status: traveling filter var $travelingCheckbox = $('<input>', {type: 'checkbox'}) .on('change', function() { reapplyFilter({status: {traveling: this.checked}}); }); var $travelingElement = $('<label>', {text: 'traveling'}).prepend($travelingCheckbox); $panel.append($travelingElement).append(', '); // status: okay filter var $okayCheckbox = $('<input>', {type: 'checkbox'}) .on('change', function() { reapplyFilter({status: {okay: this.checked}}); }); var $okayElement = $('<label>', {text: 'okay'}).prepend($okayCheckbox); $panel.append($okayElement).append(', '); // status: jail filter var $jailCheckbox = $('<input>', {type: 'checkbox'}) .on('change', function() { reapplyFilter({status: {jail: this.checked}}); }); var $jailElement = $('<label>', {text: 'in jail'}).prepend($jailCheckbox); $panel.append($jailElement).append(', '); // status: federal filter var $federalCheckbox = $('<input>', {type: 'checkbox'}) .on('change', function() { reapplyFilter({status: {federal: this.checked}}); }); var $federalElement = $('<label>', {text: 'in federal prison'}).prepend($federalCheckbox); $panel.append($federalElement).append(' or '); // status: hospital filter var $hospitalTextfield = $('<input>', {type: 'number', style: 'width: 50px'}) .on('change', function() { if (isNaN(this.value)) { reapplyFilter({status: {hospital: false}}); } else { reapplyFilter({status: {hospital: parseInt(this.value, 10)}}); } }); var $hospitalElement = $('<label>', {text: 'in hospital for more than '}) .append($hospitalTextfield) .append(' minutes'); $panel.append($hospitalElement).append('<br>'); // level filter var $levelTextfieldMin = $('<input>', {type: 'number', style: 'width: 36px'}) .on('change', function() { if (isNaN(this.value) || this.value > 99 || this.value < 0) { reapplyFilter({levelfilterMin: 0}); } else { reapplyFilter({levelfilterMin: parseInt(this.value, 10)}); } }); var $levelTextfieldMax = $('<input>', {type: 'number', style: 'width: 36px'}) .on('change', function() { if (isNaN(this.value) || this.value > 100 || this.value < 2) { reapplyFilter({levelfilterMax: 100}); } else { reapplyFilter({levelfilterMax: parseInt(this.value, 10)}); } }); var $levelElement = $('<label>', {text: 'between levels '}) .append($levelTextfieldMin) .append('and ') .append($levelTextfieldMax); // status: online/idle/offline var $onlineCheckbox = $('<input>', {type: 'checkbox'}) .on('change', function() { reapplyFilter({status: {online: this.checked}}); }); var $onlineElement = $('<label>', {text: 'online'}).prepend($onlineCheckbox); var $idleCheckbox = $('<input>', {type: 'checkbox'}) .on('change', function() { reapplyFilter({status: {idle: this.checked}}); }); var $idleElement = $('<label>', {text: 'idle'}).prepend($idleCheckbox); var $offlineCheckbox = $('<input>', {type: 'checkbox','checked':'checked'}) .on('change', function() { reapplyFilter({status: {offline: this.checked}}); }); var $offlineElement = $('<label>', {text: 'offline'}).prepend($offlineCheckbox); $panel.append('Show enemies who are ').append($levelElement).append(', ').append($onlineElement).append(', ').append($idleElement).append(', ').append($offlineElement); $panel.append('<br>(').append($filterStatusElement).append(' enemies are hidden by the filter.)'); $panel.append('<br>Sort by <select class="sortbywhat"><option value="sortdefault">Default</option><option value="respectdesc">Respect Ratio (desc)</option><option value="respectasc">Respect Ratio (asc)</option></select>'); $( ".sortbywhat" ).on('change',function() { sortLayout($(this).val()); reapplyFilter({sortby: $(this).val()}); }); // set the states of the elements according to the saved filter $travelingCheckbox[0].checked = warBaseFilter.status.traveling || false; $okayCheckbox[0].checked = warBaseFilter.status.okay || false; $jailCheckbox[0].checked = warBaseFilter.status.jail || false; $federalCheckbox[0].checked = warBaseFilter.status.federal || false; $levelTextfieldMin.val(warBaseFilter.levelfilterMin || 0); $levelTextfieldMax.val(warBaseFilter.levelfilterMax || 100); $hospitalTextfield.val(warBaseFilter.status.hospital || ''); $onlineCheckbox[0].checked = warBaseFilter.status.online !== false ? true : warBaseFilter.status.online; $idleCheckbox[0].checked = warBaseFilter.status.idle !== false ? true : warBaseFilter.status.idle; $offlineCheckbox[0].checked = warBaseFilter.status.offline !== false ? true : warBaseFilter.status.offline; $(".sortbywhat").val(warBaseFilter.sortby || "sortdefault"); sortLayout(warBaseFilter.sortby || "sortdefault"); } /** * Reapplies the war base filter - current settings will be merged with the new filter settings * @param {Object} newFilter new filter settings */ function reapplyFilter(newFilter) { $.extend(true, warBaseFilter, newFilter); localStorage.vinkuunWarBaseFilter = JSON.stringify(warBaseFilter); applyFilter(warBaseFilter); } /** * Returns the remaining hospital time in minutes * * @param {String} text The tooltip text of the hospital icon * @return {Integer} time in minutes */ function remainingHospitalTime(text) { var match = text.match(/data-time='(\d+)'/); return match[1] / 60; } // ============================================================================ // --- FEATURE: Enemy tagging // ============================================================================ var TAGS = { tbd: {text: 'Difficulty', color: 'inherit'}, easy: {text: 'Easy', color:'rgba(161, 248, 161, 1)'}, medium: {text: 'Medium', color:'rgba(231, 231, 104, 1)'}, impossible: {text: 'Impossible', color:'rgba(242, 140, 140, 1)'} }; var enemyTags = JSON.parse(localStorage.vinkuunEnemyTags || '{}'); function addEnemyTagging() { GM_addStyle( 'select.vinkuun-enemeyDifficulty { font-size: 12px; vertical-align: text-bottom }' + '.member-list li div.status, .member-list li div.act-cont { font-weight: bold }' ); var $list = $MAIN.find('.member-list > li').each(function() { var $this = $(this); var id = $this.find('.user.name').eq(0).attr('href').match(/XID=(\d+)/)[1]; $this.find('.member-icons').prepend(createDropdown($this, id)); }); } function createDropdown($li, id) { var $dropdown = $('<select>', {'class': 'vinkuun-enemeyDifficulty'}).on('change', function() { enemyTags[id] = $(this).val(); localStorage.vinkuunEnemyTags = JSON.stringify(enemyTags); updateColor($li, id); }); $.each(TAGS, function(key, value) { var $el = $('<option>', {value: key, text: value.text}); if (enemyTags[id] && key === enemyTags[id]) { $el.attr('selected', 'selected'); } $dropdown.append($el); }); updateColor($li, id); return $dropdown; } function updateColor($li, id) { if (enemyTags[id] && TAGS[enemyTags[id]]) { $li.css('background-color', TAGS[enemyTags[id]].color); } } // ============================================================================ // --- MAIN // ============================================================================ /** * Shows/Hides the control panel according to the current tab * @param {jQuery-Object} $element control panel */ function addUrlChangeCallback($element) { var urlChangeCallback = function () { if (window.location.hash === '#/tab=main' || window.location.hash === '') { $element.show(); } else { $element.hide(); } }; // call it one time to show/hide the panel after the page has been loaded urlChangeCallback(); // listen to a hash change window.onhashchange = urlChangeCallback; } /** * Initialises the script's features */ function init() { var $warBaseExtendedPanel = $('#vinkuun-extendedWarBasePanel'); if ($warBaseExtendedPanel.length !== 0) { $warBaseExtendedPanel.empty(); } else { $warBaseExtendedPanel = $('<div>', { id:'vinkuun-extendedWarBasePanel' }); $MAIN.before($warBaseExtendedPanel); } var $title = $('<div>', { 'class': 'title-black m-top10 title-toggle tablet active top-round', text: 'War Base Extended' }); $MAIN.before($title); var $panel = $('<div>', { 'class': 'cont-gray10 bottom-round cont-toggle' }); $MAIN.before($panel); $warBaseExtendedPanel.append($title).append($panel); enableWarBaseLayout(); addWarBaseFilter($panel); addEnemyTagging(); addUrlChangeCallback($warBaseExtendedPanel); } function initWarBase() { try { // observer used to apply the filter after the war base was loaded via ajax var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { // The main content is being added to the div for (var i = 0; i < mutation.addedNodes.length; i++) { if (mutation.addedNodes[i].className === 'faction-respect-wars-wp') { init(); break; } } }); }); // start listening for changes var observerTarget = $MAIN[0]; var observerConfig = { attributes: false, childList: true, characterData: false }; observer.observe(observerTarget, observerConfig); } catch (err) { console.log(err); } } function initProfileTargetIndicator() { var userId = location.search.split('=')[1]; var attackButton = $('li.action-icon-attack a'); if (enemyTags[userId]) { attackButton.css({ 'background-color': TAGS[enemyTags[userId]].color || 'rgb(132, 129, 129)', 'border-radius': '5px' }); attackButton.attr('title', 'Difficulty: ' + enemyTags[userId]); } } function initChainCounter() { $("#tcLogo").removeClass('logo'); $("#tcLogo h1").html("<br/><div id='chain'></div>") setInterval(chainLoop, 1000); } function chainLoop() { // this function is depreciated and not used anymore because of new torn rules var prefix; if (location.protocol != 'https:') { prefix = 'http'; } else { prefix = 'https'; } $.get(prefix+"://www.torn.com/templates/sidebar/chainbar.php?factionID=19", function(data){ $("#chain").html(data); }); } function checkforMain() { if ($("#faction-main").css('display') == "block") { $("#vinkuun-extendedWarBasePanel").show(); } else { $("#vinkuun-extendedWarBasePanel").hide(); } } setInterval(checkforMain, 500); if (location.href.indexOf('torn.com/profiles.php?XID=') !== -1) { initProfileTargetIndicator(); } else if (location.href.indexOf('factions.php?step=your') !== -1) { initWarBase(); } //else if (location.href.indexOf('torn.com/loader2.php?sid=getInAttack') !== -1) { // initChainCounter(); //}