HALO Armory Valiant

Faction armory drug debts tracker with deposit management, clean usernames, and reset per member.

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

// ==UserScript==
// @name         HALO Armory Valiant
// @namespace    http://tampermonkey.net/
// @version      2.4
// @description  Faction armory drug debts tracker with deposit management, clean usernames, and reset per member.
// @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,
        "vicodin": 800,
        "ketamine": 2000,
        "shrooms": 2000,
        "cannabis": 4500,
        "speed": 6000,
        "pcp": 7500,
        "opium": 23000,
        "lsd": 32000,
        "ecstasy": 40000
    };

    let factionKey = GM_getValue("factionAPIKey", null);
    let debts = GM_getValue("factionDebts", {});
    let deposits = GM_getValue("factionDeposits", {}); // stores deposited drugs
    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; }
      .resetBtn, .depositBtn {
        cursor: pointer;
        background: #eee;
        border: 1px solid #aaa;
        border-radius: 4px;
        font-size: 12px;
        margin-left: 6px;
        padding: 1px 4px;
      }
      .resetBtn:hover, .depositBtn: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 Debts & Deposits</div>
      <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();

    function stripTags(str) {
        return str ? str.replace(/<[^>]*>/g, "").trim() : "";
    }

    // Deposit drugs manually
    function depositDrug(user, drug, quantity) {
        if (!deposits[user]) deposits[user] = {};
        if (!deposits[user][drug]) deposits[user][drug] = { deposit: 0, used: 0, price: DRUG_PRICES[drug] || 0 };

        deposits[user][drug].deposit += quantity;
        deposits[user][drug].used = 0;
        debts[user] = 0; // reset debt when depositing
        GM_setValue("factionDeposits", deposits);
        GM_setValue("factionDebts", debts);
        loadLogs();
        console.log(`${user} deposited ${quantity} of ${drug}. Debt reset.`);
    }
    window.depositDrug = depositDrug; // global for console use

    async function loadLogs() {
        if (!factionKey) {
            document.getElementById("debtLog").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("debtLog").innerHTML = "Error: " + data.error.error;
                return;
            }

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

            Object.entries(logs).forEach(([logId, entry]) => {
                const text = entry.news.toLowerCase();
                let matchedDrug = Object.keys(DRUG_PRICES).find(d => text.includes(d));
                if (matchedDrug) {
                    let userMatch = entry.news.match(/^(.+?) used/i);
                    let rawUser = userMatch ? userMatch[1] : "Unknown";
                    let user = stripTags(rawUser);

                    if (!processedLogs[logId]) {
                        // Initialize user's deposit object if missing
                        if (!deposits[user]) deposits[user] = {};
                        if (!deposits[user][matchedDrug]) deposits[user][matchedDrug] = { deposit: 0, used: 0, price: DRUG_PRICES[matchedDrug] };

                        let drugData = deposits[user][matchedDrug];

                        if (drugData.deposit > drugData.used) {
                            // Use deposited dose
                            drugData.used++;
                        } else {
                            // No deposit, add debt
                            debts[user] = (debts[user] || 0) + DRUG_PRICES[matchedDrug];
                        }

                        processedLogs[logId] = true;
                    }
                }
            });

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

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

            if (Object.keys(debts).length === 0 && Object.keys(deposits).length === 0) {
                debtDiv.innerHTML += "No activity.";
            } else {
                const users = new Set([...Object.keys(debts), ...Object.keys(deposits)]);
                users.forEach(u => {
                    let row = document.createElement("div");
                    let depInfo = deposits[u] ? Object.entries(deposits[u]).map(([d, info]) => `${d}: ${info.used}/${info.deposit}`).join(", ") : "";
                    let debtInfo = debts[u] ? debts[u].toLocaleString() : "0";
                    row.textContent = `${u} | Debt: ${debtInfo} | Deposits: ${depInfo}`;

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

                    row.appendChild(resetBtn);

                    let depositBtn = document.createElement("button");
                    depositBtn.className = "depositBtn";
                    depositBtn.textContent = "➕";
                    depositBtn.addEventListener("click", () => {
                        let drug = prompt("Enter drug name:").toLowerCase();
                        let qty = parseInt(prompt("Enter quantity:"), 10);
                        if (drug && !isNaN(qty)) depositDrug(u, drug, qty);
                    });

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

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

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

    if (factionKey) loadLogs();

})();

QingJ © 2025

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