NPC Attack Time Newsfeed

Add NPC attack time to the news ticker using Loot Rangers for Torn

当前为 2024-02-08 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         NPC Attack Time Newsfeed
// @namespace    npc.timing
// @version      v1.0.0
// @description  Add NPC attack time to the news ticker using Loot Rangers for Torn
// @author       IceBlueFire [776]
// @license      MIT
// @match        https://www.torn.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=torn.com
// @grant        unsafeWindow
// @grant        GM_xmlhttpRequest
// @require      https://code.jquery.com/jquery-1.8.2.min.js
// @connect      api.lzpt.io
// ==/UserScript==

const color = "#8abeef"; // Any hex-code
const format = 24; // 12 or 24
const local = false; // true or false

const lzpt = getAttackTimes();
const { fetch: originalFetch } = unsafeWindow;
unsafeWindow.fetch = async (...args) => {
    var [resource, config] = args;
    var response = await originalFetch(resource, config);
    const json = () => response.clone().json()
    .then((data) => {
        data = { ...data };
        if(response.url.indexOf('?sid=newsTicker') != -1) {
            lzpt.then(function(result) {
                var attackOrder = '';
                var attackString = '';
                var attackLink = '';
                var attackTarget = 0;

                /* If there's no clear time set */
                if(result.time.clear == 0) {
                    attackString = result.time.reason || (attackString = 'NPC attacking will resume after '+result.time.reason, 'No attack currently set.');
                } else {
                    /* Build the string for the attack order */
                    $.each(result.order, function(key, value) {
                        if(result.npcs[value].next){
                            /* If there's an attack happening right now, cross out NPCs that are in the hospital */
                            if(result.time.attack === true) {
                                if(result.npcs[value].hosp_out >= result.time.current) {
                                    attackOrder += '<span style="text-decoration: line-through">'+result.npcs[value].name+'</span>, ';
                                } else {
                                    attackOrder += result.npcs[value].name+', ';
                                }
                            } else {
                                attackOrder += result.npcs[value].name+', ';
                            }
                        }
                        /* Adjust the current target based on if an attack is going and who isn't in the hospital yet */
                        if(result.time.attack === true) {
                            if(result.npcs[value].hosp_out <= result.time.current) { // Check if the NPC is currently out of the hospital
                                if(attackTarget == 0) {
                                    attackTarget = value;
                                }
                            }
                        }
                    });

                    /* Check if target has been set, otherwise default to first in attack order */
                    if(attackTarget == 0) {
                        attackTarget = result.order[0];
                    }

                    /* Clean up the attack order string */
                    attackOrder = attackOrder.slice(0, -2)+'.';

                    /* Check if an attack is currently happening and adjust the message accordingly */
                    if(result.time.attack === true) {
                        attackString = 'NPC attack is underway! Get in there and get some loot!';
                        attackLink = 'loader.php?sid=attack&user2ID='+attackTarget;
                    } else {
                        attackString = 'NPC attack set for '+utcformat(result.time.clear)+'. Order is: '+attackOrder;
                        attackLink = 'loader.php?sid=attack&user2ID='+attackTarget;
                    }
                }

                /* Insert the custom news item into the news ticker */
                let attackItem = {ID: 0, headline: '<span style="color:'+color+'; font-weight: bold;">'+attackString+'</span>', countdown: true, endtime: result.time.clear, link: attackLink, isGlobal: false, type: 'generalMessage'};
                data.headlines.unshift(attackItem);
            }, function(err) {
                console.log(err); // Error: "It broke"
            });
        }
        return data
    })

    response.json = json;
    response.text = async () =>JSON.stringify(await json());

    return response;
};

/* Format the time in the appropriate fashion */
function utcformat(d){
    d= new Date(d * 1000);
    if(local) {
        var tail= ' LT', D= [d.getFullYear(), d.getMonth()+1, d.getDate()],
            T= [d.getHours(), d.getMinutes(), d.getSeconds()];
    } else {
        var tail= ' TCT', D= [d.getUTCFullYear(), d.getUTCMonth()+1, d.getUTCDate()],
            T= [d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds()];
    }
    if(format == 12) {
        /* 12 hour format */
        if(+T[0]> 12){
            T[0]-= 12;
            tail= 'PM '+tail;
        }
        else tail= 'AM '+tail;
    }
    var i= 3;
    while(i){
        --i;
        if(D[i]<10) D[i]= '0'+D[i];
        if(T[i]<10) T[i]= '0'+T[i];
    }
    return T.join(':')+ tail;
}

/* Fetch the NPC details from Loot Rangers */
async function getAttackTimes() {
    return new Promise(resolve => {
        const request_url = `https://api.lzpt.io/loot`;
        GM_xmlhttpRequest ({
            method:     "GET",
            url:        request_url,
            headers:    {
                "Content-Type": "application/json"
            },
            onload: response => {
                try {
                    const data = JSON.parse(response.responseText);
                    if(!data) {
                        console.log('No response from Loot Rangers');
                    } else {
                        return resolve(data)
                    }
                }
                catch (e) {
                    console.error(e);
                }

            },
            onerror: (e) => {
                console.error(e);
            }
        })
    });
}