dont-touch-my-apikey-config

configure apiKey for all script

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/493751/1368224/dont-touch-my-apikey-config.js

  1. // ==UserScript==
  2. // @name dont-touch-my-apikey-config
  3. // @namespace akm.torn.dtm-apikey-config
  4. // @version 0.1
  5. // @description configure apiKey for all script
  6. // @author Anonknee Moose
  7. // @license GNU GPLv3
  8. // @run-at document-end
  9. // @match https://www.torn.com/*
  10. // @grant GM_xmlhttpRequest
  11. // @connect tornstats.com
  12. // License information: https://www.gnu.org/licenses/gpl-3.0.html
  13. // License summary: You may copy, distribute and modify the software as long as you track changes/dates in source files. Any modifications to or software including (via compiler) GPL-licensed code must also be made available under the GPL along with build & install instructions.
  14. // Usage request: Under this license you are not required to request access to use this software. You are free to use it as you see fit.
  15. // Warranty: This software is provided as-is with no warranty or guarantee of support. Use at your own risk.
  16. // The why: When this script was originally copied it was in the public domain under the same license
  17. // as the original author's other scripts. The original author has been actively trying to remove
  18. // this script from the internet. This script is being maintained to keep it available for users
  19. // who still find it useful. If the original author would like this script removed, please contact
  20. // Greasy Fork with a proper reason, and they will remove it if they see fit.
  21. // If you are the original author and would like to take over maintenance of this script, please
  22. // contact Greasy Fork, and they will transfer ownership to you with my prior consent.
  23. // If you are the original author and would like to discuss the license or any other matter, please
  24. // contact me through Greasy Fork and I will respond as soon as possible.
  25. // Changes: The original script used the term "finally" which is a reserved word in JavaScript. This has been changed to "dtmb".
  26. //
  27. // ==/UserScript==
  28.  
  29. myAddStyle(`
  30. .dtmb-api-config {
  31. position: absolute;
  32. background: var(--main-bg);
  33. text-align: center;
  34. left: 0;
  35. top: 0;
  36. width: 100%;
  37. height: 100%;
  38. }
  39.  
  40. .dtmb-api-config > * {
  41. margin: 0 5px;
  42. padding: 5px;
  43. }
  44. `);
  45.  
  46. let apiKeyLib = localStorage["dtmb.torn.api"] || null;
  47. let apiKeyCheck = false;
  48.  
  49. function JSONparse(str) {
  50. try { return JSON.parse(str); }
  51. catch (e) { console.log(e); }
  52. return null;
  53. }
  54.  
  55. function checkApiKey(key, callb) {
  56. GM_xmlhttpRequest({
  57. method: "GET",
  58. url: `https://www.tornstats.com/api/v1/${key}`,
  59. onload: (resp) => {
  60. if (resp.status == 429) {
  61. callb("Couldn't check (rate limit)");
  62. return;
  63. }
  64. if (resp.status != 200) {
  65. callb(`Couldn't check (status code ${resp.status})`);
  66. return;
  67. }
  68.  
  69. let j = JSONparse(resp.responseText);
  70. if (!j) {
  71. callb("Couldn't check (unexpected response)");
  72. return;
  73. }
  74.  
  75. if (!j.status) {
  76. callb(j.message || "Wrong API key?");
  77. }
  78. else {
  79. apiKeyLib = key;
  80. localStorage["dtmb.torn.api"] = key;
  81. callb(true);
  82. }
  83. },
  84. onabort: () => callb("Couldn't check (aborted)"),
  85. onerror: () => callb("Couldn't check (error)"),
  86. ontimeout: () => callb("Couldn't check (timeout)")
  87. })
  88. }
  89.  
  90. function addAPIKeyInput(node) {
  91. if (!node) return;
  92. if (document.getElementsByClassName("dtmb-api-config")[0]) return;
  93.  
  94. node.style.position = "relative";
  95.  
  96. let apiKeyNode = document.createElement("div");
  97. apiKeyNode.className = "text faction-names dtmb-api-config";
  98. apiKeyNode.style.display = (!apiKeyLib) ? "block" : "none";
  99.  
  100. let apiKeyText = document.createElement("span");
  101. apiKeyText.innerHTML = ((!apiKeyLib) ? "Set" : "Update") + " your API key: ";
  102.  
  103. let apiKeyInput = document.createElement("input");
  104.  
  105. let apiKeySave = document.createElement("input");
  106. apiKeySave.type = "button";
  107. apiKeySave.value = "Save";
  108.  
  109. let apiKeyClose = document.createElement("input");
  110. apiKeyClose.type = "button";
  111. apiKeyClose.value = "Close";
  112. apiKeyNode.appendChild(apiKeyText);
  113. apiKeyNode.appendChild(apiKeyInput);
  114. apiKeyNode.appendChild(apiKeySave);
  115. apiKeyNode.appendChild(apiKeyClose);
  116.  
  117. function checkApiKeyCb(r) {
  118. if (r === true) {
  119. apiKeyNode.style.display = "none";
  120. apiKeyInput.value = "";
  121. } else {
  122. apiKeyNode.style.display = "block";
  123. apiKeyText.innerHTML = `${r}: `;
  124. }
  125. }
  126.  
  127. apiKeySave.addEventListener("click", () => {
  128. apiKeyText.innerHTML = "Checking key";
  129. checkApiKey(apiKeyInput.value, checkApiKeyCb);
  130. });
  131.  
  132. apiKeyClose.addEventListener("click", () => {
  133. apiKeyNode.style.display = "none";
  134. });
  135.  
  136. let apiKeyButton = document.createElement("a");
  137. apiKeyButton.className = "t-clear h c-pointer line-h24 right ";
  138. apiKeyButton.innerHTML = `
  139. <span>Update API Key</span>
  140. `;
  141.  
  142. apiKeyButton.addEventListener("click", () => {
  143. apiKeyText.innerHTML = "Update your API key: ";
  144. apiKeyNode.style.display = "block";
  145. });
  146.  
  147. if (node === nodeLink) node.appendChild(apiKeyButton);
  148. else if (node === nodeContent) node.querySelector("#top-page-links-list").appendChild(apiKeyButton);
  149.  
  150. node.appendChild(apiKeyNode);
  151.  
  152. if (apiKeyLib && !apiKeyCheck) {
  153. apiKeyCheck = true;
  154. checkApiKey(apiKeyLib, checkApiKeyCb);
  155. }
  156. }
  157.  
  158. function myAddStyle(cssCode) {
  159. let style = document.createElement("style");
  160. style.innerHTML = cssCode;
  161. document.head.appendChild(style);
  162. }
  163.  
  164. const nodeLink = document.querySelector("div[class^='titleContainer']")
  165. const nodeContent = document.querySelector(".content-title")
  166.  
  167. if (nodeLink) addAPIKeyInput(nodeLink);
  168. else if (nodeContent) addAPIKeyInput(nodeContent);