HALO

Faction armory drug logs with debt tracking and reset button per member (✅ works now)

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

// ==UserScript==
// @name         HALO
// @namespace    http://tampermonkey.net/
// @version      2.1.2
// @description  Faction armory drug logs with debt tracking and reset button per member (✅ works now)
// @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.";

            // Clear debt log container
            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或关注我们的公众号极客氢云获取最新地址