War End

Adds a toggle-able side bar to estimate War End for a given faction.

当前为 2025-07-25 提交的版本,查看 最新版本

// ==UserScript==
// @name         War End
// @version      Alpha1.2
// @namespace    https://gf.qytechs.cn/
// @description  Adds a toggle-able side bar to estimate War End for a given faction. 
// @author       Gravity0000
// @supportURL   https://www.torn.com/profiles.php?XID=2131364
// @license      MIT
// @match        https://www.torn.com/*
// @grant        GM_xmlhttpRequest
// @grant        GM_addStyle
// @connect      api.torn.com
// ==/UserScript==

(function() {
    'use strict';

    // Create container
    var container = document.createElement('div');
    container.id = 'myScriptContainer';
    document.body.appendChild(container);

    // Create the API input box
    var apiBox = document.createElement('input');
    apiBox.type = 'text';
    apiBox.id = 'myAPIBox';
    apiBox.placeholder = 'Enter API Here';
    container.appendChild(apiBox);

    // Create Info Box
    var infoBox = document.createElement('div');
    infoBox.id = 'myInfoBox';
    infoBox.innerHTML = 'Initial Info';
    container.appendChild(infoBox);

    // Create the Faction input box
    var textBox = document.createElement('input');
    textBox.type = 'number';
    textBox.id = 'myTextBox';
    textBox.placeholder = 'Blank or Faction ID';
    container.appendChild(textBox);

    textBox.addEventListener('keypress', (event) => {
        var key = event.keyCode || event.which;
        if ((key >= 48 && key <= 57) || key === 8) {
            return true;
        }else {
            event.preventDefault();
        }

    })

    // Create the Lead input box
    var leadBox = document.createElement('input');
    leadBox.type = 'number';
    leadBox.id = 'myTextBox';
    leadBox.placeholder = 'Blank or Est. Lead';
    container.appendChild(leadBox);

    leadBox.addEventListener('keypress', (event) => {
        var key = event.keyCode || event.which;
        //let strKey = String.fromCharCode(key); || strKey === "-"
        if ((key >= 48 && key <= 57) || key === 8 ) {
            return true;
        }else {
            event.preventDefault();
        }

    })
    // Create Toggle Button
    const toggleButton = document.createElement('button');
    toggleButton.innerText = 'WarEnd';
    toggleButton.style.backgroundColor = 'green';
    toggleButton.style.position = 'fixed';
    toggleButton.style.top = '65%';
    toggleButton.style.right = '0%';
    toggleButton.style.zIndex = '9999'; // Ensure button is on top
    toggleButton.style.cursor = 'pointer';
    document.body.appendChild(toggleButton); // Add button to the page

    // Add an event listener to the button
    toggleButton.addEventListener('click', () => {
        if (container) {
            if (container.style.display === 'none') {
                container.style.display = ''; // Restore original display or set to 'block'
            } else {
                container.style.display = 'none'; // Hide the element
            }
        }
    })

    // Setup toggle visability button
    if (container) {
         container.style.display = 'none';
    }
    const savedAPI = localStorage.getItem("savedAPIValue");
        if (savedAPI) {
            apiBox.value = savedAPI;
        }
    const savedFaction = localStorage.getItem("savedFactionValue");
        if (savedFaction) {
            textBox.value = savedFaction;
        }

    // Create the update button
    var updateButton = document.createElement('button');
    updateButton.id = 'myUpdateButton';
    updateButton.textContent = 'Update';
    container.appendChild(updateButton);

    // Add a click event listener to the update button and do stuff
    updateButton.addEventListener('click', function() {
        const faction_id = textBox.value; // Get value from box
        const apiKey = apiBox.value; // Get value from box
        //const estLead = leadBox.value;
        localStorage.setItem("savedAPIValue", apiKey); //Store API key localy
        localStorage.setItem("savedFactionValue", faction_id); //Store Facton ID localy
        //localStorage.setItem("savedEstValue", estLead); //Store EST localy
        GM_xmlhttpRequest({
            method: "GET",
            url: `https://api.torn.com/v2/faction/${faction_id}/wars/?selections=basic&key=${apiKey}&comment=warend`,
            onload: function(response) {
                if (response.status === 200) {
                    const data = JSON.parse(response.responseText);
                    console.log("TornCity API Response:", data);
                    //console.log("TornCity API Response:", data.wars.ranked.start);
                    //console.log ("test", data.wars.ranked.end);
                    //console.log ("test", data.wars.ranked.end.length());
                    //console.log ("test", data.wars.ranked.length());
                    //console.log ("test", data.wars.ranked.size());
                    if (data.wars && data.wars.ranked !== null) {
                        const instant2 = data.wars.ranked.start;
                        const instant1 = Date.now();
                        const firstScore = data.wars.ranked.factions[0].score;
                        const secondScore = data.wars.ranked.factions[1].score;
                        const differ = Math.abs(+secondScore - +firstScore);
                        const targetScore = data.wars.ranked.target;
                        let scoreLeft = +targetScore - +differ;
                        const timePassedMs = Math.abs(instant1 - (instant2 * 1000)); // Make time standard value with miliseconds and get difference
                        const hoursDifference = Math.floor(timePassedMs / (1000 * 60 * 60)); // Convert from miliseconds to hours and rounds down. Change Math.floor to Math.ceil to round up
                        let hrsLeft = 0;
                        let onePercent = 0;
                        let passedHrs = 0;
                        let daysLeft = 0;
                        let minLeft = 0;
                        let oneHund = 0;
                        let newLead = parseInt(leadBox.value, 10);
                        // Calculate 1% of initial target score
                        if (hoursDifference < 24) {
                            onePercent = targetScore / 100;
                        } else {
                            passedHrs = (hoursDifference - 24);
                            onePercent = Math.round(targetScore / (100 - passedHrs));
                        }
                        oneHund = onePercent * 100;
                        if (leadBox.value != ''){
                        if (newLead <= targetScore && newLead > 0 ){
                            infoBox.innerHTML = leadBox.value;
                            scoreLeft = +targetScore - newLead;
                        }else {
                            infoBox.innerHTML = "Error Max lead =" + targetScore;
                            return;
                        }
                        }
                        while (scoreLeft > 0) { // Calculate hours left
                            scoreLeft -= onePercent;
                            hrsLeft++;
                        }
                        if (!data.wars.ranked.end){
                            minLeft = Math.floor(60 - ((timePassedMs / (1000 * 60))-(hoursDifference * 60)));
                        }
                        if (hrsLeft < 24) {
                            infoBox.innerHTML = (hrsLeft + "H " + minLeft + "M<br>Untill WarEnd."); // Update info box
                        }else {
                            daysLeft = Math.floor(hrsLeft / 24);
                            hrsLeft = hrsLeft - (daysLeft * 24);
                            infoBox.innerHTML = (daysLeft + "D " + hrsLeft + "H " + minLeft + "M<br>Untill WarEnd."); // Update info box
                        }
                        //infoBox.innerHTML = oneHund;
                    } else {
                        infoBox.innerHTML = ("Invalid Waring Faction ID");
                    }
                    if (data.error.code === 2) {
                        infoBox.innerHTML = ("Invalid API Key");
                    }
                } else {
                    infoBox.innerHTML = "ERROR";
                    console.error("TornCity API Error:", response.status, response.statusText);
                }

            },
                onerror: function(error) {
                    console.error("Network Error:", error);
                    infoBox.innerHTML = "NETWORK ERROR";
                }
        });
    }, false);

     GM_addStyle(`
        #myScriptContainer {
            position: fixed;
            width: 130px;
            top: 70%;
            right: 0%;
            background-color: #f0f0f0;
            border: 1px solid #ccc;
            padding: 10px;
            z-index: 9999;
            display: flex;
            flex-direction: column;
            gap: 5px;
        }
        #myAPIBox {
            padding: 5px;
            border: 1px solid #ddd;
        }
        #myInfoBox {
            padding: 5px;
            text-align: center;
            background-color: #f2f2f2;
        }
        #myTextBox {
            padding: 5px;
            border: 1px solid #ddd;
        }
        #myUpdateButton {
            padding: 5px 10px;
            background-color: #007bff;
            color: white;
            border: none;
            cursor: pointer;
        }
    `);

    // Add the items into the box
    //document.body.appendChild(button);
    //document.body.appendChild(textBox);
    //document.body.appendChild(infoBox);
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址