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      1.2.A
// @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

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