HALO

Faction armory drug logs with debt tracking and reset button per member (clean names, no links shown in debts)

当前为 2025-09-14 提交的版本,查看 最新版本

// ==UserScript==
// @name         HALO
// @namespace    http://tampermonkey.net/
// @version      2.2.0
// @description  Faction armory drug logs with debt tracking and reset button per member (clean names, no links shown in debts)
// @author       Nova
// @match        https://www.torn.com/*
// @grant        GM_addStyle
// @grant        GM_getValue
// @grant        GM_setValue
// ==/UserScript==

(function() {
'use strict';

const factionId = "41990"; // your faction ID  
const DRUG_PRICES = {  
    "xanax": 760000,  
    "ecstasy": 0,  
    "ketamine": 0,  
    "lsd": 0,  
    "speed": 0,  
    "pcp": 0,  
    "shrooms": 0,  
    "opium": 0,  
    "vicodin": 0,  
    "cannabis": 0  
};  

let factionKey = GM_getValue("factionAPIKey", null);  
let debts = GM_getValue("factionDebts", {});  
let processedLogs = GM_getValue("processedLogs", {});  

GM_addStyle(`  
  #armoryPanel {  
    position: fixed;  
    bottom: 0;  
    right: 0;  
    width: 26%;  
    height: 55%;  
    background: white;  
    color: #000;  
    font-family: monospace;  
    font-size: 12px;  
    border: 1px solid #444;  
    border-radius: 8px 8px 0 0;  
    overflow-y: auto;  
    padding: 8px;  
    z-index: 9999;  
    display: none;  
  }  
  #armoryHeader { font-weight: bold; margin-bottom: 6px; }  
  .armoryItem { margin: 2px 0; }  
  .user {color:black; font-weight:bold;}  
  .drug {color:purple;}  
  .resetBtn {  
    cursor: pointer;  
    background: #eee;  
    border: 1px solid #aaa;  
    border-radius: 4px;  
    font-size: 12px;  
    margin-left: 6px;  
    padding: 1px 4px;  
  }  
  .resetBtn:hover {  
    background: #ccc;  
  }  
  #bubbleBtn {  
    position: fixed;  
    bottom: 20px;  
    right: 20px;  
    background:#222;  
    color:#fff;  
    border-radius:50%;  
    width:36px;  
    height:36px;  
    font-size:18px;  
    cursor:pointer;  
    display:flex;  
    justify-content:center;  
    align-items:center;  
    z-index:10000;  
  }  
`);  

const panel = document.createElement("div");  
panel.id = "armoryPanel";  
panel.innerHTML = `  
  <div id="armoryHeader">Faction Drugs Log</div>  
  <div id="armoryLog">Loading...</div>  
  <hr>  
  <div id="debtLog">Debts loading...</div>  
`;  
document.body.appendChild(panel);  

const bubble = document.createElement("div");  
bubble.id = "bubbleBtn";  
bubble.textContent = "💊";  
document.body.appendChild(bubble);  

let minimized = true;  
function togglePanel() {  
    minimized = !minimized;  
    panel.style.display = minimized ? "none" : "block";  
}  
bubble.addEventListener("click", togglePanel);  

function askKey() {  
    let key = prompt("Enter your Faction (Armory) API Key:", factionKey || "");  
    if (key) {  
        GM_setValue("factionAPIKey", key);  
        factionKey = key;  
        loadLogs();  
    }  
}  
if (!factionKey) askKey();  

async function loadLogs() {  
    if (!factionKey) {  
        document.getElementById("armoryLog").innerHTML = "No API key set.";  
        return;  
    }  
    try {  
        let url = `https://api.torn.com/faction/${factionId}?selections=armorynews&key=${factionKey}`;  
        let res = await fetch(url);  
        let data = await res.json();  
        if (data.error) {  
            document.getElementById("armoryLog").innerHTML = "Error: " + data.error.error;  
            return;  
        }  

        const logs = data.armorynews;  
        if (!logs) {  
            document.getElementById("armoryLog").innerHTML = "No drug activity.";  
            return;  
        }  

        const drugLogs = [];  
        Object.entries(logs).forEach(([logId, entry]) => {  
            const text = entry.news.toLowerCase();  

            let matchedDrug = Object.keys(DRUG_PRICES).find(d => text.includes(d));  
            if (matchedDrug) {  
                const userMatch = entry.news.match(/^(.+?) used/i);  
                const user = userMatch ? userMatch[1].trim() : "Unknown";  

                const date = new Date(entry.timestamp * 1000);  
                const time = `${String(date.getHours()).padStart(2,'0')}:${String(date.getMinutes()).padStart(2,'0')} ${date.getDate()}/${date.getMonth()+1}/${date.getFullYear()}`;  

                drugLogs.push({user, drug: matchedDrug, time, id: logId});  

                if (!processedLogs[logId]) {  
                    const charge = DRUG_PRICES[matchedDrug] || 0;  
                    if (charge > 0) {  
                        debts[user] = (debts[user] || 0) + charge;  
                    }  
                    processedLogs[logId] = true;  
                }  
            }  
        });  

        GM_setValue("factionDebts", debts);  
        GM_setValue("processedLogs", processedLogs);  

        drugLogs.sort((a,b)=> b.id - a.id);  
        const last20 = drugLogs.slice(0,20);  
        let html = "<ul>";  
        last20.forEach(e => {  
            html += `<li class="armoryItem">  
                        <span class="user">${e.user}</span> used   
                        <span class="drug">${e.drug}</span> [${e.time}]  
                     </li>`;  
        });  
        html += "</ul>";  
        document.getElementById("armoryLog").innerHTML = html || "No drug activity.";  

        // Debts clean  
        let debtDiv = document.getElementById("debtLog");  
        debtDiv.innerHTML = "<b>Debts:</b><br>";  

        if (Object.keys(debts).length === 0) {  
            debtDiv.innerHTML += "No debts.";  
        } else {  
            Object.entries(debts).forEach(([u, d]) => {  
                let row = document.createElement("div");  
                row.textContent = `${u}: ${d.toLocaleString()}`;  

                let btn = document.createElement("button");  
                btn.className = "resetBtn";  
                btn.textContent = "✅";  
                btn.addEventListener("click", (e) => {  
                    e.preventDefault();  
                    e.stopPropagation();  
                    debts[u] = 0;  
                    GM_setValue("factionDebts", debts);  
                    loadLogs();  
                });  

                row.appendChild(btn);  
                debtDiv.appendChild(row);  
            });  
        }  

    } catch (e) {  
        document.getElementById("armoryLog").innerHTML = "Request failed.";  
    }  
}  

setInterval(() => {  
    if (!minimized && factionKey) loadLogs();  
}, 45000);  

if (factionKey) loadLogs();

})();

QingJ © 2025

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