Shoplifting alert

Display a red square if cameras or guards are down in Big Al's. Clicking the red square removes notification for 30 minutes.

当前为 2023-09-11 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Shoplifting alert
  3. // @namespace http://torn.city.com.dot.com.com
  4. // @version 1.4.5.1
  5. // @description Display a red square if cameras or guards are down in Big Al's. Clicking the red square removes notification for 30 minutes.
  6. // @author Adobi
  7. // @match *://*/*
  8. // @grant GM_setValue
  9. // @grant GM_getValue
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. ///////////////////////////////// USER DEFINED VARIABLES /////////////////////////////////
  17.  
  18. const timeOut = 1800 * 1000 // 30 minute time out when you click red square. Change if you want.
  19. const copyCat = false // Set to true if you want a message put in your clipboard when you click the red square.
  20. // Purpose of message is to paste in faction chat to notify your friends that they should shoplift.
  21. // Message below, change as you wish.
  22. const baseMessage = "Shoplift now for special ammo https://www.torn.com/loader.php?sid=crimes#/shoplifting"
  23. const guardsDown = "Guards are gone at Big Al's - "
  24. const camerasDown = "Cameras are down at Big Al's - "
  25. const bothDown = "Cameras AND guards are down at Big Al's, holy shit - "
  26.  
  27. ////////// END OF USER DEFINED VARIABLES. Change things below at your own risk. //////////
  28.  
  29.  
  30. // Function to create and display yellow square with the option to enter API key
  31. function displayYellowSquare() {
  32. const yellowSquare = document.createElement('div');
  33. yellowSquare.id = 'yellowSquare';
  34. yellowSquare.style.position = 'fixed';
  35. yellowSquare.style.left = '0';
  36. yellowSquare.style.top = '0';
  37. yellowSquare.style.width = '100px';
  38. yellowSquare.style.height = '100px';
  39. yellowSquare.style.backgroundColor = 'yellow';
  40. yellowSquare.style.zIndex = '99999999';
  41. yellowSquare.style.display = 'flex'; // Use flexbox for centering
  42. yellowSquare.style.cursor = 'pointer'; // Change cursor to pointer
  43.  
  44. // Create a container div for centered text
  45. const textContainer = document.createElement('div');
  46. textContainer.style.margin = 'auto'; // Center horizontally
  47. textContainer.style.textAlign = 'center'; // Center text
  48. textContainer.style.display = 'flex';
  49. textContainer.style.flexDirection = 'column'; // Center vertically
  50.  
  51. // Create text nodes for the yellow square with a line break
  52. const yellowTextNode0 = document.createTextNode('Shoplift alerter');
  53. const lineBreak = document.createElement('br');
  54. const yellowTextNode1 = document.createTextNode('Click here to');
  55. const lineBreak2 = document.createElement('br');
  56. const yellowTextNode2 = document.createTextNode('supply API key');
  57.  
  58.  
  59. // Append the text nodes and line break to the text container
  60. textContainer.appendChild(yellowTextNode0);
  61. textContainer.appendChild(lineBreak);
  62. textContainer.appendChild(yellowTextNode1);
  63. textContainer.appendChild(lineBreak2);
  64. textContainer.appendChild(yellowTextNode2);
  65.  
  66. // Append the text container to the yellow square
  67. yellowSquare.appendChild(textContainer);
  68.  
  69. // Append the yellow square to the body (if it's not already added)
  70. if (!document.getElementById('yellowSquare')) {
  71. document.body.appendChild(yellowSquare);
  72. }
  73.  
  74. // Add a click event listener to the yellow square
  75. yellowSquare.addEventListener('click', () => {
  76. const apiKey = prompt('Enter your API key:');
  77. if (apiKey) {
  78. // Store the API key with GM_setValue
  79. GM_setValue('shoplifting_api_key', apiKey);
  80. yellowSquare.remove(); // Remove the yellow square after entering the API key
  81. fetchAndDisplayData(); // Run an API call with the new key
  82. }
  83. });
  84. }
  85.  
  86. // Check if the API key is already stored using GM_getValue
  87. const apiKey = GM_getValue('shoplifting_api_key', '');
  88.  
  89. // If the API key is not stored, display the yellow square
  90. if (!apiKey) {
  91. displayYellowSquare();
  92. }
  93.  
  94. // Function to create and display the red square text, and remove it if security is back up
  95. function displayRedSquare(camera, guard) {
  96. const existingRedSquare = document.getElementById('redSquare');
  97. if (existingRedSquare) {
  98. existingRedSquare.remove();
  99. }
  100. // Check if both camera and guard values are false
  101. if (camera === false && guard === false) {
  102. return; // Exit the function, as there's no need to create the red square
  103. }
  104.  
  105. // Create or update the red square div
  106. const redSquare = document.getElementById('redSquare') || document.createElement('div');
  107. redSquare.id = 'redSquare';
  108. redSquare.style.position = 'fixed';
  109. redSquare.style.left = '0';
  110. redSquare.style.top = '0';
  111. redSquare.style.width = '100px';
  112. redSquare.style.height = '100px';
  113. redSquare.style.backgroundColor = 'red';
  114. redSquare.style.zIndex = '99999999';
  115. redSquare.style.display = 'flex'; // Use flexbox for centering
  116.  
  117. // Create a container div for centered text
  118. const textContainer = document.createElement('div');
  119. textContainer.style.margin = 'auto'; // Center horizontally
  120. textContainer.style.textAlign = 'center'; // Center text
  121. textContainer.style.display = 'flex';
  122. textContainer.style.flexDirection = 'column'; // Center vertically
  123.  
  124. // Create text nodes for "camera" and "guard" values
  125. let cameraTextNode = document.createTextNode(`Camera: Online`);
  126. let guardTextNode = document.createTextNode(`Guards: On duty`);
  127. if (camera) { cameraTextNode = document.createTextNode(`Camera: Offline`); }
  128. if (guard) { guardTextNode = document.createTextNode(`Guards: Gone`); }
  129. const lineBreak = document.createElement('br');
  130.  
  131. // Append the text nodes and line break to the text container
  132. textContainer.appendChild(cameraTextNode);
  133. textContainer.appendChild(lineBreak);
  134. textContainer.appendChild(guardTextNode);
  135.  
  136. // Append the text container to the red square
  137. redSquare.appendChild(textContainer);
  138.  
  139. // Append the red square to the body (if it's not already added)
  140. if (!document.getElementById('redSquare')) {
  141. document.body.appendChild(redSquare);
  142. }
  143.  
  144. // Add a click event listener to the red square
  145. redSquare.addEventListener('click', () => {
  146. // Put a message into clipboard for easy pasting to faction chat, if copyCat is enabled
  147. if (copyCat === true) {
  148. let copyMessage = "";
  149. if (camera === true && guard === true) {
  150. copyMessage = bothDown + baseMessage;
  151. } else {
  152. if (guard === true) {
  153. copyMessage = guardsDown + baseMessage;
  154. } else {
  155. copyMessage = camerasDown + baseMessage;
  156. }
  157. }
  158. navigator.clipboard.writeText(copyMessage)
  159. }
  160. // Set camera and guard values to false
  161. GM_setValue('cameraValue', false);
  162. GM_setValue('guardValue', false);
  163.  
  164. // Set the timestamp to the current timestamp plus a time defined by the user at the top of this script
  165. GM_setValue('lastCallTime', Date.now() + timeOut);
  166.  
  167. // Remove the red square div
  168. redSquare.remove();
  169. });
  170. }
  171.  
  172. // Function to fetch API data and display the red square
  173. function fetchAndDisplayData() {
  174. const currentTime = Date.now();
  175. const lastCallTime = GM_getValue('lastCallTime', 0);
  176. // Check if at least 60 seconds have passed since the last API call
  177. if (currentTime - lastCallTime >= 60000) {
  178.  
  179. // Check if the API key is already stored using GM_getValue
  180. const apiKey = GM_getValue('shoplifting_api_key', '');
  181. // If the API key is not stored, display the yellow square
  182. if (!apiKey) {
  183. displayYellowSquare();
  184. }
  185.  
  186. fetch(`https://api.torn.com/torn/?selections=shoplifting&key=${apiKey}`)
  187. .then(response => response.json())
  188. .then(data => {
  189. // Check if there's an error in the API response
  190. if (data.error && data.error.error === "Incorrect key") {
  191. GM_setValue('shoplifting_api_key', "");
  192. displayYellowSquare();
  193. } else {
  194. // Get the values for "camera" and "guard" from the API data
  195. const camera = data.shoplifting.big_als[0].disabled;
  196. const guard = data.shoplifting.big_als[1].disabled;
  197.  
  198. // Store the values of "camera" and "guard"
  199. GM_setValue('cameraValue', camera);
  200. GM_setValue('guardValue', guard);
  201. GM_setValue('lastCallTime', currentTime); // Store the current timestamp
  202.  
  203. // Call the displayRedSquare function with camera and guard values
  204. displayRedSquare(camera, guard);
  205. }
  206. })
  207. .catch(error => console.error('there was an API Error:', error));
  208. }
  209. }
  210.  
  211. // Initial run after 2 seconds with saved values of camera and guard, or fetch new data if values don't exist
  212. setTimeout(() => {
  213. const currentTime = Date.now();
  214. const lastCallTime = GM_getValue('lastCallTime', 0);
  215. // Check if the last saved timestamp is more than 60 seconds ago or if cameraValue and guardValue don't exist
  216. if (
  217. currentTime - lastCallTime >= 60000 ||
  218. GM_getValue('cameraValue') === undefined ||
  219. GM_getValue('guardValue') === undefined
  220. ) {
  221. // If any of the conditions are met, fetch new data
  222. fetchAndDisplayData();
  223. } else {
  224. // Otherwise, use the old saved values for camera and guard
  225. const savedCamera = GM_getValue('cameraValue', false); // Default to false if not saved
  226. const savedGuard = GM_getValue('guardValue', false); // Default to false if not saved
  227. displayRedSquare(savedCamera, savedGuard);
  228. }
  229. }, 2000);
  230.  
  231. // Repeat every 10 seconds
  232. setInterval(fetchAndDisplayData, 10000);
  233. //displayYellowSquare() //debugging
  234. //displayRedSquare(true, true) //debugging
  235. })();