Torn Chain Panel

This is a work in progress, it is no where near completed. It is NOT for use for anyone other than my faction. It is probably not even a good script lol. thanks for reading. heres what it does. A collapsible utility panel for my faction to manually fetch their assigned chain number and a hit timer during wars. This tool helps faction members stay organized during chain events without having someone always there to monitor the chain.

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/544476/1637545/Torn%20Chain%20Panel.js

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Torn Chain Panel
// @namespace    http://tampermonkey.net/
// @version      0.4
// @description  Collapsible panel for chain # + timer
// @author       BuzzC137
// @match        https://www.torn.com/*
// @grant        none
// @license      Proprietary
// ==/UserScript==

/*
Copyright © 2025 BuzzC137

This script is proprietary and not open source.

You MAY NOT:
- Copy, modify, distribute, or use this script in any form without explicit written permission from the author.

Exception:
Torn City developers and staff are permitted to review or access this script for moderation, verification, or security purposes.

Unauthorized use may result in revocation of access or further action.
*/


(function () {
  'use strict';

  const discordUsername = 'buzzc137';

  const styles = `
    #chainPanel {
      position: fixed;
      top: 100px;
      left: 20px;
      background: rgba(24, 24, 24, 0.95);
      color: #ccc;
      font-family: Verdana, sans-serif;
      font-size: 12px;
      border: 1px solid #555;
      border-radius: 5px;
      padding: 10px;
      z-index: 9999;
      width: 220px;
      box-shadow: 0 0 10px #000;
    }
    #chainPanel.collapsed .panel-body {
      display: none;
    }
    #chainPanel .panel-header {
      font-weight: bold;
      color: #0f0;
      cursor: move;
      margin-bottom: 8px;
    }
    #chainPanel button,
    #chainPanel input {
      width: 100%;
      margin-bottom: 6px;
      padding: 6px;
      border: none;
      border-radius: 3px;
      font-size: 11px;
    }
    #chainPanel button {
      background: #333;
      color: white;
      cursor: pointer;
    }
    #chainPanel button:hover {
      background: #555;
    }
    #chainPanel .toggle {
      background: #1c1c1c;
      color: #aaa;
      font-size: 10px;
      text-align: center;
      padding: 4px;
      border-top: 1px solid #444;
      cursor: pointer;
    }
    #chainTabs {
      display: flex;
      justify-content: space-around;
      margin-bottom: 6px;
    }
    #chainTabs button {
      font-size: 10px;
      padding: 4px;
    }
  `;

  const styleTag = document.createElement('style');
  styleTag.innerText = styles;
  document.head.appendChild(styleTag);

  const panel = document.createElement('div');
  panel.id = 'chainPanel';
  panel.innerHTML = `
    <div class="panel-header">Chain Tool</div>
    <div class="panel-body">
      <input type="number" id="chainTimerInput" placeholder="Timer (sec)">
      <button id="getChainBtn">Get My Chain #</button>
      <button id="startTimerBtn">Start Timer</button>
      <div id="chainTabs">
        <button disabled>Tab 1</button>
        <button disabled>Tab 2</button>
      </div>
    </div>
    <div class="toggle">▲ Collapse</div>
  `;
  document.body.appendChild(panel);

  // Collapse toggle
  const toggle = panel.querySelector('.toggle');
  toggle.addEventListener('click', () => {
    panel.classList.toggle('collapsed');
    toggle.innerText = panel.classList.contains('collapsed') ? '▼ Expand' : '▲ Collapse';
  });

  // Drag logic
  const header = panel.querySelector('.panel-header');
  let isDragging = false, offsetX = 0, offsetY = 0;
  header.addEventListener('mousedown', (e) => {
    isDragging = true;
    offsetX = e.clientX - panel.offsetLeft;
    offsetY = e.clientY - panel.offsetTop;
  });
  document.addEventListener('mousemove', (e) => {
    if (isDragging) {
      panel.style.left = `${e.clientX - offsetX}px`;
      panel.style.top = `${e.clientY - offsetY}px`;
    }
  });
  document.addEventListener('mouseup', () => isDragging = false);

  // Fetch Chain Number
  const fetchBtn = panel.querySelector('#getChainBtn');
  fetchBtn.addEventListener('click', () => {
    fetch(`https://removing-maldives-driving-money.trycloudflare.com/chain/${discordUsername}`)
      .then(res => res.json())
      .then(data => {
        if (data.chain) {
          alert(`Your assigned chain number is: #${data.chain}`);
        } else {
          alert('You don’t have a chain number yet.');
        }
      })
      .catch(err => {
        alert('Error fetching chain number. Is the bot running?');
        console.error('Fetch error:', err);
      });
  });

  // Timer logic
  let timer;
  panel.querySelector('#startTimerBtn').addEventListener('click', () => {
    const seconds = parseInt(document.querySelector('#chainTimerInput').value) || 10;

    // Red flash
    const flash = document.createElement('div');
    flash.style.position = 'fixed';
    flash.style.top = 0;
    flash.style.left = 0;
    flash.style.width = '100%';
    flash.style.height = '100%';
    flash.style.backgroundColor = 'red';
    flash.style.opacity = '0.5';
    flash.style.zIndex = 999;
    document.body.appendChild(flash);
    setTimeout(() => document.body.removeChild(flash), 500);

    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      const audio = new Audio('https://www.soundjay.com/button/sounds/beep-07.mp3');
      audio.play();
      console.log("Timer complete – make your hit!");
    }, seconds * 1000);
  });
})();