Is it Down? (Updated)

Pulls from TrackerStatus API and displays status on supported trackers

  1. // ==UserScript==
  2. // @name Is it Down? (Updated)
  3. // @version 0.6.1
  4. // @namespace https://trackerstatus.info/
  5. // @description Pulls from TrackerStatus API and displays status on supported trackers
  6. // @match https://redacted.sh/*
  7. // @match https://orpheus.network/*
  8. // @match https://passthepopcorn.me/*
  9. // @match https://broadcasthe.net/*
  10. // @match https://gazellegames.net/*
  11. // @match https://alpharatio.cc/*
  12. // @match https://anthelion.me/*
  13. // @match https://nebulance.io/*
  14. // @grant GM.xmlHttpRequest
  15. // @license MIT
  16. // ==/UserScript==
  17.  
  18. (function() {
  19. 'use strict';
  20.  
  21. const Settings = {
  22. showIfStable: false,
  23. checkInterval: 120000, // check every 2 mins by default
  24. apiEndpoints: {
  25. 'redacted.sh': 'https://red.trackerstatus.info/api/all/',
  26. 'orpheus.network': 'https://ops.trackerstatus.info/api/all/',
  27. 'passthepopcorn.me': 'https://ptp.trackerstatus.info/api/all/',
  28. 'broadcasthe.net': 'https://btn.trackerstatus.info/api/all/',
  29. 'gazellegames.net': 'https://ggn.trackerstatus.info/api/all/',
  30. 'alpharatio.cc': 'https://ar.trackerstatus.info/api/all/',
  31. 'anthelion.me': 'https://ant.trackerstatus.info/api/all/',
  32. 'nebulance.io': 'https://nbl.trackerstatus.info/api/all/'
  33. }
  34. };
  35.  
  36. const styles = `
  37. .tracker-status {
  38. position: fixed;
  39. z-index: 9999;
  40. box-sizing: border-box;
  41. width: 100%;
  42. display: none;
  43. padding: 0.2rem;
  44. bottom: 0;
  45. left: 0;
  46. font-size: 14px;
  47. text-align: center;
  48. }
  49. .tracker-status--stable { background-color: #056B00; }
  50. .tracker-status--offline { background-color: #A00E0E; }
  51. .tracker-status--unstable { background-color: #FFA500; }
  52. .tracker-status--both { background-color: #FF4B33; }
  53. .tracker-status__message {
  54. color: white;
  55. font-weight: bold;
  56. margin: 0;
  57. }
  58. .tracker-status__link {
  59. color: white;
  60. text-decoration: underline;
  61. }
  62. body {
  63. transition: margin-bottom 0.3s ease;
  64. }
  65. `;
  66.  
  67. function createStatusElement() {
  68. const trackerStatus = document.createElement('div');
  69. trackerStatus.className = 'tracker-status';
  70.  
  71. const message = document.createElement('p');
  72. message.className = 'tracker-status__message';
  73.  
  74. trackerStatus.appendChild(message);
  75. document.body.append(trackerStatus);
  76.  
  77. const styleElement = document.createElement('style');
  78. styleElement.textContent = styles;
  79. document.head.appendChild(styleElement);
  80.  
  81. return trackerStatus;
  82. }
  83.  
  84. function updateStatus(trackerStatus) {
  85. const currentDomain = window.location.hostname;
  86. const apiUrl = Settings.apiEndpoints[currentDomain];
  87.  
  88. if (!apiUrl) {
  89. console.error('No API endpoint found for the current domain');
  90. return;
  91. }
  92.  
  93. GM.xmlHttpRequest({
  94. method: 'POST',
  95. url: apiUrl,
  96. headers: {
  97. "X-Requested-With": "XMLHttpRequest"
  98. },
  99. onload: function(response) {
  100. const messageElement = trackerStatus.querySelector('.tracker-status__message');
  101.  
  102. if (response.status >= 200 && response.status < 400) {
  103. const services = JSON.parse(response.responseText);
  104. const downServices = Object.entries(services).filter(service => service[1].Status === '0');
  105. const unstableServices = Object.entries(services).filter(service => service[1].Status === '2');
  106.  
  107. if (downServices.length > 0 && unstableServices.length > 0) {
  108. trackerStatus.className = 'tracker-status tracker-status--both';
  109. messageElement.innerHTML = `The following services are currently offline or unstable: ${[...downServices, ...unstableServices].map(service => service[0]).join(', ')}. <a class="tracker-status__link" href="${apiUrl.replace('/api/all/', '')}">More info</a>`;
  110. trackerStatus.style.display = 'block';
  111. } else if (downServices.length > 0) {
  112. trackerStatus.className = 'tracker-status tracker-status--offline';
  113. messageElement.innerHTML = `The following services are currently offline: ${downServices.map(service => service[0]).join(', ')}. <a class="tracker-status__link" href="${apiUrl.replace('/api/all/', '')}">More info</a>`;
  114. trackerStatus.style.display = 'block';
  115. } else if (unstableServices.length > 0) {
  116. trackerStatus.className = 'tracker-status tracker-status--unstable';
  117. messageElement.innerHTML = `The following services are unstable: ${unstableServices.map(service => service[0]).join(', ')}. <a class="tracker-status__link" href="${apiUrl.replace('/api/all/', '')}">More info</a>`;
  118. trackerStatus.style.display = 'block';
  119. } else {
  120. trackerStatus.className = 'tracker-status tracker-status--stable';
  121. messageElement.textContent = 'All systems operational.';
  122. trackerStatus.style.display = Settings.showIfStable ? 'block' : 'none';
  123. }
  124. } else {
  125. console.error('Error fetching tracker status');
  126. trackerStatus.className = 'tracker-status tracker-status--offline';
  127. messageElement.innerHTML = 'Error fetching tracker status.';
  128. trackerStatus.style.display = 'block';
  129. }
  130.  
  131. const statusHeight = trackerStatus.offsetHeight;
  132. document.body.style.marginBottom = trackerStatus.style.display !== 'none' ? `${statusHeight}px` : '0';
  133. },
  134. onerror: function(error) {
  135. console.error('Error fetching tracker status:', error);
  136. const messageElement = trackerStatus.querySelector('.tracker-status__message');
  137. trackerStatus.className = 'tracker-status tracker-status--offline';
  138. messageElement.innerHTML = 'Error fetching tracker status.';
  139. trackerStatus.style.display = 'block';
  140.  
  141. const statusHeight = trackerStatus.offsetHeight;
  142. document.body.style.marginBottom = `${statusHeight}px`;
  143. }
  144. });
  145. }
  146.  
  147. const trackerStatus = createStatusElement();
  148. updateStatus(trackerStatus);
  149. setInterval(() => updateStatus(trackerStatus), Settings.checkInterval);
  150.  
  151. window.addEventListener('resize', () => {
  152. const statusHeight = trackerStatus.offsetHeight;
  153. document.body.style.marginBottom = trackerStatus.style.display !== 'none' ? `${statusHeight}px` : '0';
  154. });
  155. })();

QingJ © 2025

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