AtoZ Utilities DEV

Utilities that are frequently used in other scripts.

目前为 2021-05-06 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/404603/928315/AtoZ%20Utilities%20DEV.js

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