Greasy Fork 支持简体中文。

AtoZ Utilities DEV

Utilities that are frequently used in other scripts.

目前為 2020-06-18 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.cn-greasyfork.org/scripts/404603/817748/AtoZ%20Utilities%20DEV.js

  1. // ==UserScript==
  2. // @name AtoZ Utilities DEV
  3. // @namespace AtoZ
  4. // @author AlienZombie [2176352]
  5. // @credit DeKleineKobini [2114440] {For using various concepts and pieces of code to achieve my objectives}
  6. // @credit Jox [1714547] {For using various concepts and pieces of code to achieve my objectives}
  7. // @description Utilities that are frequently used in other scripts.
  8. // @version 1.0.0.16
  9. // @source https://greasyfork.org/en/scripts/404603-atoz-utilities
  10. // @grant GM_getValue
  11. // @grant GM_setValue
  12. // ==/UserScript==
  13.  
  14.  
  15. initialize();
  16.  
  17. function initialize() {
  18. Number.prototype.format = function(n, x) {
  19. var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\.' : '$') + ')';
  20. return this.toFixed(Math.max(0, ~~n)).replace(new RegExp(re, 'g'), '$&,');
  21. };
  22. }
  23.  
  24. const localStorageAPIKey = "AtoZ_apikey";
  25. const localStorageDKKAPIKey = "dkkutils_apikey";
  26. const tornPlayerIdCookieName = "uid";
  27.  
  28. var Logging = {
  29. Identifier: "*** AtoZ ***",
  30. Debugging: {
  31. Active: false,
  32. Identifier: "*** AtoZ DEBUG ***"
  33. }
  34. }
  35.  
  36. var thisScriptName = "Utilities";
  37. var tornAPIKey = null;
  38. var tornPlayerId = getCookie(tornPlayerIdCookieName);
  39.  
  40. //#region General Purpose
  41. var setCheckbox = function(origin) {
  42. createDebugLog(thisScriptName, "setCheckbox", " origin Id: " + origin.target.id + " value" + origin.target.checked ? "1" : "0")
  43. GM_setValue(origin.target.id, origin.target.checked ? "1" : "0");
  44. };
  45.  
  46. var setText = function(origin) {
  47. createDebugLog(thisScriptName, "setText", " origin Id: " + origin.target.id + " value" + origin.target.value)
  48. GM_setValue(origin.target.id, origin.target.value);
  49. };
  50.  
  51. function Startup(needAPI, activateDebugging) {
  52. if (!validateEmpty(needAPI) && needAPI) {
  53. if (validateEmpty(tornAPIKey)) {
  54. requestAPIKey();
  55. }
  56. }
  57.  
  58. if (!validateEmpty(activateDebugging) && activateDebugging) {
  59. Logging.Debugging.Active = activateDebugging;
  60. }
  61. }
  62.  
  63. function validateEmpty(value) {
  64. if (!value || value === undefined || value == "undefined" || value === null || value == "null" || value === ""){
  65. return true;
  66. }
  67. else {
  68. return false;
  69. }
  70. }
  71.  
  72. function verifyJSONString(JSONString) {
  73. let response = {
  74. isError: null,
  75. errorName: null,
  76. errorMessage: null,
  77. content: null
  78. };
  79.  
  80. let json = null;
  81.  
  82. if (validateEmpty(JSONString)) {
  83. response.isError = true;
  84. response.errorName = "EmptyString";
  85. response.errorMessage = "The JSON string is empty.";
  86. return response;
  87. }
  88. try {
  89. json = JSON.parse(JSONString);
  90. } catch (e) {
  91. response.isError = true;
  92. response.errorName = e.errorName;
  93. response.errorMessage = e.errorMessage;
  94. return response;
  95. }
  96.  
  97. response.isError = false;
  98. response.content = json;
  99. return response;
  100. }
  101.  
  102. function observeMutationsFull(root, callback, options) {
  103. if (!options) options = {
  104. childList: true
  105. };
  106.  
  107. new MutationObserver(callback).observe(root, options);
  108. }
  109.  
  110. function observeMutations(root, selector, runOnce, callback, options, callbackRemoval) {
  111. var ran = false;
  112. observeMutationsFull(root, function(mutations, me) {
  113. var check = $(selector);
  114.  
  115. if (check.length) {
  116. if (runOnce) me.disconnect();
  117.  
  118. ran = true;
  119. callback(mutations, me);
  120. } else if (ran) {
  121. ran = false;
  122. if (callbackRemoval) callbackRemoval(mutations, me);
  123. }
  124. }, options);
  125. }
  126.  
  127. function ajax(callback) {
  128. let funcName = "ajax";
  129.  
  130. $(document).ajaxComplete((event, xhr, settings) => {
  131. if (xhr.readyState > 3 && xhr.status == 200) {
  132. if (settings.url.indexOf("torn.com/") < 0) settings.url = "torn.com" + (settings.url.startsWith("/") ? "" : "/") + settings.url;
  133. var page = settings.url.substring(settings.url.indexOf("torn.com/") + "torn.com/".length, settings.url.indexOf(".php"));
  134.  
  135. var json, uri;
  136.  
  137. let verifyJSON = verifyJSONString(xhr.responseText);
  138. createDebugLog(thisScriptName, funcName, "Ajax Json verify response:");
  139. logDebugObject(verifyJSON);
  140. if (verifyJSON.isError) {
  141. createDebugLog(thisScriptName, funcName, "JSON Error: " + verifyJSON.errorName + " - " + verifyJSON.errorMessage + " ResponseText: " + xhr.responseText);
  142. uri = getUrlParams(xhr.responseText);
  143. } else if (verifyJSON.content.error) {
  144. createDebugLog(thisScriptName, funcName, "ajax Error: " + verifyJSON.content.error.code)
  145. uri = getUrlParams(xhr.responseText);
  146. } else {
  147. json = verifyJSON.content;
  148. }
  149.  
  150. callback(page, json, uri, xhr, settings);
  151. }
  152. });
  153. }
  154.  
  155. function getUrlParams(url, prop) {
  156. var params = {};
  157. var search = decodeURIComponent(((url) ? url : window.location.href).slice(window.location.href.indexOf('?') + 1));
  158. var definitions = search.split('&');
  159.  
  160. definitions.forEach(function(val, key) {
  161. var parts = val.split('=', 2);
  162. params[parts[0]] = parts[1];
  163. });
  164.  
  165. return (prop && prop in params) ? params[prop] : params;
  166. }
  167.  
  168.  
  169. //#endregion General Purpose
  170.  
  171. //#region API Key
  172.  
  173. function validateAPIKey(apiKey) {
  174. let funcName = "validateAPIKey";
  175.  
  176. if (validateEmpty(apiKey)) {
  177. if (validateEmpty(tornAPIKey)) {
  178. createDebugLog(thisScriptName, funcName, "[failure]: " + apiKey);
  179. return null;
  180. }
  181. else {
  182. apiKey = tornAPIKey;
  183. }
  184. }
  185.  
  186. if (apiKey.length != 16) {
  187. createDebugLog(thisScriptName, funcName, "[failure]: " + apiKey);
  188. return null;
  189. }
  190.  
  191. createDebugLog(thisScriptName, funcName, "[success]: " + apiKey);
  192. return apiKey;
  193. }
  194.  
  195. function storeAPIKey(apiKey) {
  196. let funcName = "storeAPIKey";
  197.  
  198. createDebugLog(thisScriptName, funcName, "Checking key for storage")
  199. let apiVar = validateAPIKey(apiKey);
  200.  
  201. if (validateEmpty(apiVar)) {
  202. createDebugLog(thisScriptName, funcName, "[failure]: " + apiVar);
  203. localStorage.removeItem(localStorageAPIKey);
  204. }
  205. else{
  206. localStorage.setItem(localStorageAPIKey, apiVar);
  207. createDebugLog(thisScriptName, funcName, "[success]: " + apiVar);
  208. }
  209.  
  210. tornAPIKey = apiVar;
  211. }
  212.  
  213. function clearAPIKey() {
  214. localStorage.removeItem(localStorageAPIKey);
  215. tornAPIKey = null;
  216. createDebugLog(thisScriptName, "clearAPIKey", "User API Key removed.")
  217. }
  218.  
  219. function retrieveAPIKey() {
  220. let funcName = "retrieveAPIKey";
  221.  
  222. createDebugLog(thisScriptName, funcName, "Check for local API Key")
  223. let apiVar = validateAPIKey(localStorage.getItem(localStorageAPIKey));
  224. if (!validateEmpty(apiVar)) {
  225. createDebugLog(thisScriptName, funcName, "[success]: " + apiVar);
  226. return apiVar;
  227. }
  228. //Maybe the user has DKK scripts, so use that key instead:
  229. createDebugLog(thisScriptName, funcName, "No local key, trying DKK key")
  230. apiVar = validateAPIKey(localStorage.getItem(localStorageDKKAPIKey));
  231. if (!validateEmpty(apiVar)) {
  232. storeAPIKey(apiVar);
  233. return apiVar;
  234. }
  235.  
  236. createDebugLog(thisScriptName, funcName, "[failure]:" + apiVar);
  237. return null
  238. }
  239.  
  240. function requestAPIKey() {
  241. let funcName = "requestAPIKey";
  242.  
  243. tornAPIKey = retrieveAPIKey();
  244. if (validateEmpty(tornAPIKey)) {
  245. createDebugLog(thisScriptName, funcName, "No api key")
  246. let response = prompt("Enter your API key for the AtoZ script(s) to work: ");
  247. tornAPIKey = validateAPIKey(response);
  248. if (!validateEmpty(tornAPIKey)) {
  249. createDebugLog(thisScriptName, funcName, "[VALID] key obtained from user: " + tornAPIKey)
  250. storeAPIKey(tornAPIKey);
  251. } else {
  252. createDebugLog(thisScriptName, funcName, "[INVALID] key obtained from user: " + tornAPIKey)
  253. alert("The key you entered is invalid.\nWithout it, this script cannot work.\nRefresh to try again.")
  254. }
  255. }
  256. }
  257.  
  258. //#endregion API Key
  259.  
  260. //#region Logging
  261.  
  262. function createDebugLog(scriptName, functionName, debugMessage) {
  263. if (!Logging.Debugging.Active) {
  264. return;
  265. }
  266.  
  267. console.log(Logging.Debugging.Identifier + " [" + scriptName + "] - [" + functionName + "] - " + debugMessage);
  268. }
  269.  
  270. function logDebugObject(object) {
  271. if (!Logging.Debugging.Active) {
  272. return;
  273. }
  274.  
  275. console.log(JSON.parse(JSON.stringify(object)));
  276. }
  277.  
  278. function createLog(scriptName, functionName, message) {
  279. console.log(Logging.Identifier + " [" + scriptName + "] - [" + functionName + "] - " + message);
  280. }
  281.  
  282. function logObject(object) {
  283. console.log(JSON.parse(JSON.stringify(object)));
  284. }
  285.  
  286. //#endregion Logging
  287.  
  288. //#region Torn API
  289.  
  290. var tornAPIParts = {
  291. User: {
  292. Key: "user",
  293. Selections: {
  294. Ammo: "ammo",
  295. Attacks: "attacks",
  296. AttacksFull: "attacksfull",
  297. Bars: "bars",
  298. Basic: "basic",
  299. BattleStats: "battlestats",
  300. Bazaar: "bazaar",
  301. Cooldowns: "cooldowns",
  302. Crimes: "crimes",
  303. Discord: "discord",
  304. Display: "display",
  305. Education: "education",
  306. Events: "events",
  307. Gym: "gym",
  308. Hof: "hof",
  309. Honors: "honors",
  310. Icons: "icons",
  311. Inventory: "inventory",
  312. JobPoints: "jobpoints",
  313. Medals: "medals",
  314. Merits: "merits",
  315. Messages: "messages",
  316. Money: "money",
  317. Networth: "networth",
  318. Notifications: "notifications",
  319. Perks: "perks",
  320. PersonalStats: "personalstats",
  321. Profile: "profile",
  322. Properties: "properties",
  323. ReceivedEvents: "receivedevents",
  324. Refills: "refills",
  325. Revives: "revives",
  326. RevivesFull: "revivesfull",
  327. Stocks: "stocks",
  328. Timestamp: "timestamp",
  329. Travel: "travel",
  330. WeaponExp: "weaponexp",
  331. WorkStats: "workstats"
  332. }
  333. },
  334. Properties: {
  335. Key: "property",
  336. Selections: null
  337. },
  338. Faction: {
  339. Key: "faction",
  340. Selections: null
  341. },
  342. Company: {
  343. Key: "company",
  344. Selections: null
  345. },
  346. ItemMarket: {
  347. Key: "market",
  348. Selections: null
  349. },
  350. Torn: {
  351. Key: "torn",
  352. Selections: null
  353. }
  354. }
  355.  
  356. function tornAPIRequest(part, selections, key) {
  357. let funcName = "tornAPIRequest";
  358.  
  359. createDebugLog(thisScriptName, funcName, `Torn API request for Part: ${part} Player Id: ${tornPlayerId} Selections: ${selections}`);
  360. if (validateEmpty(key)) {
  361. key = tornAPIKey;
  362. }
  363.  
  364. return new Promise((resolve, reject) => {
  365.  
  366. GM_xmlhttpRequest({
  367. method: "GET",
  368. url: `https://api.torn.com/${part}/${tornPlayerId}?selections=${selections}&key=${key}`,
  369. onreadystatechange: function(response) {
  370. if (response.readyState > 3 && response.status === 200) {
  371. createDebugLog(thisScriptName, funcName, "Torn API response received: ")
  372. logDebugObject(response);
  373. let verifyJSON = verifyJSONString(response.responseText);
  374. createDebugLog(thisScriptName, funcName, "Torn API Json verify response:");
  375. logDebugObject(verifyJSON);
  376. if (verifyJSON.isError) {
  377. createDebugLog(thisScriptName, funcName, "JSON Error: " + verifyJSON.errorName + " - " + verifyJSON.errorMessage + " ResponseText: " + response.responseText);
  378. reject("JSON Error", response.responseText);
  379. return;
  380. }
  381.  
  382. resolve(verifyJSON.content);
  383.  
  384. if (verifyJSON.content.error) {
  385. createDebugLog(thisScriptName, funcName, "Torn API Error: " + verifyJSON.content.error.code)
  386. if (verifyJSON.content.error.code == 2) {
  387. clearAPIKey();
  388. }
  389. }
  390. }
  391. },
  392. onerror: function(errorResponse) {
  393. createDebugLog(thisScriptName, funcName, "httpRequest Error: " + errorResponse);
  394. reject('httpRequest error.');
  395. }
  396. })
  397. }).catch(err => {
  398. createDebugLog(thisScriptName, funcName, "Promise Error: " + err);
  399. });
  400. }
  401.  
  402. //#endregion Torn API
  403.  
  404. //#region Cookies
  405.  
  406. function getCookie(cname) {
  407. var name = cname + "=";
  408. var ca = document.cookie.split(';');
  409. for(var i = 0; i < ca.length; i++) {
  410. var c = ca[i];
  411. while (c.charAt(0) == ' ') {
  412. c = c.substring(1);
  413. }
  414. if (c.indexOf(name) == 0) {
  415. return c.substring(name.length, c.length);
  416. }
  417. }
  418. return "";
  419. }
  420.  
  421. //#endregion