AtoZ Utilities DEV

Utilities that are frequently used in other scripts.

Tento skript by neměl být instalován přímo. Jedná se o knihovnu, kterou by měly jiné skripty využívat pomocí meta příkazu // @require https://update.greatest.deepsurf.us/scripts/404603/941646/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.29
  8. // @source https://greatest.deepsurf.us/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(pageFilter, 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)
  134. settings.url = "torn.com" + (settings.url.startsWith("/") ? "" : "/") + settings.url;
  135. var page = settings.url.substring(settings.url.indexOf("torn.com/") + "torn.com/".length, settings.url.indexOf(".php"));
  136.  
  137. if (pageFilter && (page == pageFilter)) {
  138. var json, uri;
  139.  
  140. let verifyJSON = verifyJSONString(xhr.responseText);
  141. createDebugLog(thisScriptName, funcName, "Ajax Json verify response:");
  142. logDebugObject(verifyJSON);
  143. if (verifyJSON.isError) {
  144. createDebugLog(thisScriptName, funcName, "JSON Error: " + verifyJSON.errorName + " - " + verifyJSON.errorMessage + " ResponseText: " + xhr.responseText);
  145. uri = getUrlParams(xhr.responseText);
  146. } else if (verifyJSON.content.error) {
  147. createDebugLog(thisScriptName, funcName, "ajax Error: " + verifyJSON.content.error.code)
  148. uri = getUrlParams(xhr.responseText);
  149. } else {
  150. json = verifyJSON.content;
  151. }
  152. callback(page, json, uri, xhr, settings);
  153. }
  154.  
  155. return null;
  156. }
  157. });
  158. }
  159.  
  160. function getUrlParams(url, prop) {
  161. var params = {};
  162. var search = decodeURIComponent(((url) ? url : window.location.href).slice(window.location.href.indexOf('?') + 1));
  163. var definitions = search.split('&');
  164.  
  165. definitions.forEach(function(val, key) {
  166. var parts = val.split('=', 2);
  167. params[parts[0]] = parts[1];
  168. });
  169.  
  170. return (prop && prop in params) ? params[prop] : params;
  171. }
  172.  
  173.  
  174. //#endregion General Purpose
  175.  
  176. //#region API Key
  177.  
  178. function validateAPIKey(apiKey) {
  179. let funcName = "validateAPIKey";
  180.  
  181. if (validateEmpty(apiKey)) {
  182. if (validateEmpty(tornAPIKey)) {
  183. createDebugLog(thisScriptName, funcName, "[failure]: " + apiKey);
  184. return null;
  185. }
  186. else {
  187. apiKey = tornAPIKey;
  188. }
  189. }
  190.  
  191. if (apiKey.length != 16) {
  192. createDebugLog(thisScriptName, funcName, "[failure]: " + apiKey);
  193. return null;
  194. }
  195.  
  196. createDebugLog(thisScriptName, funcName, "[success]: " + apiKey);
  197. return apiKey;
  198. }
  199.  
  200. function storeAPIKey(apiKey) {
  201. let funcName = "storeAPIKey";
  202.  
  203. createDebugLog(thisScriptName, funcName, "Checking key for storage")
  204. let apiVar = validateAPIKey(apiKey);
  205.  
  206. if (validateEmpty(apiVar)) {
  207. createDebugLog(thisScriptName, funcName, "[failure]: " + apiVar);
  208. localStorage.removeItem(localStorageAPIKey);
  209. }
  210. else{
  211. localStorage.setItem(localStorageAPIKey, apiVar);
  212. createDebugLog(thisScriptName, funcName, "[success]: " + apiVar);
  213. }
  214.  
  215. tornAPIKey = apiVar;
  216. }
  217.  
  218. function clearAPIKey() {
  219. localStorage.removeItem(localStorageAPIKey);
  220. tornAPIKey = null;
  221. createDebugLog(thisScriptName, "clearAPIKey", "User API Key removed.")
  222. }
  223.  
  224. function retrieveAPIKey() {
  225. let funcName = "retrieveAPIKey";
  226.  
  227. createDebugLog(thisScriptName, funcName, "Check for local API Key")
  228. let apiVar = validateAPIKey(localStorage.getItem(localStorageAPIKey));
  229. if (!validateEmpty(apiVar)) {
  230. createDebugLog(thisScriptName, funcName, "[success]: " + apiVar);
  231. return apiVar;
  232. }
  233. //Maybe the user has DKK scripts, so use that key instead:
  234. createDebugLog(thisScriptName, funcName, "No local key, trying DKK key")
  235. apiVar = validateAPIKey(localStorage.getItem(localStorageDKKAPIKey));
  236. if (!validateEmpty(apiVar)) {
  237. storeAPIKey(apiVar);
  238. return apiVar;
  239. }
  240.  
  241. createDebugLog(thisScriptName, funcName, "[failure]:" + apiVar);
  242. return null
  243. }
  244.  
  245. function requestAPIKey() {
  246. let funcName = "requestAPIKey";
  247.  
  248. tornAPIKey = retrieveAPIKey();
  249. if (validateEmpty(tornAPIKey)) {
  250. createDebugLog(thisScriptName, funcName, "No api key")
  251. let response = prompt("Enter your API key for the AtoZ script(s) to work: ");
  252. tornAPIKey = validateAPIKey(response);
  253. if (!validateEmpty(tornAPIKey)) {
  254. createDebugLog(thisScriptName, funcName, "[VALID] key obtained from user: " + tornAPIKey)
  255. storeAPIKey(tornAPIKey);
  256. } else {
  257. createDebugLog(thisScriptName, funcName, "[INVALID] key obtained from user: " + tornAPIKey)
  258. alert("The key you entered is invalid.\nWithout it, this script cannot work.\nRefresh to try again.")
  259. }
  260. }
  261. }
  262.  
  263. //#endregion API Key
  264.  
  265. //#region Logging
  266.  
  267. function createFatalLog(scriptName, functionName, errorMessage) {
  268. console.log(Logging.Debugging.Identifier, "!!! FATAL ERROR !!! [", scriptName, "] - [", functionName, "] - ", errorMessage);
  269. throw new FatalError(errorMessage);
  270. }
  271.  
  272. function createDebugLog(scriptName, functionName, debugMessage) {
  273. if (!Logging.Debugging.Active) {
  274. return;
  275. }
  276.  
  277. console.log(Logging.Debugging.Identifier, " [", scriptName, "] - [", functionName, "] - ", debugMessage);
  278. }
  279.  
  280. function logDebugObject(object) {
  281. if (!Logging.Debugging.Active) {
  282. return;
  283. }
  284.  
  285. console.log(JSON.parse(JSON.stringify(object)));
  286. }
  287.  
  288. function createLog(scriptName, functionName, message) {
  289. console.log(Logging.Identifier, " [", scriptName, "] - [", functionName, "] - ", message);
  290. }
  291.  
  292. function logObject(object) {
  293. console.log(JSON.parse(JSON.stringify(object)));
  294. }
  295.  
  296. //#endregion Logging
  297.  
  298. //#region Torn API
  299.  
  300. var tornAPIParts = {
  301. User: {
  302. Key: "user",
  303. Selections: {
  304. Ammo: "ammo",
  305. Attacks: "attacks",
  306. AttacksFull: "attacksfull",
  307. Bars: "bars",
  308. Basic: "basic",
  309. BattleStats: "battlestats",
  310. Bazaar: "bazaar",
  311. Cooldowns: "cooldowns",
  312. Crimes: "crimes",
  313. Discord: "discord",
  314. Display: "display",
  315. Education: "education",
  316. Events: "events",
  317. Gym: "gym",
  318. Hof: "hof",
  319. Honors: "honors",
  320. Icons: "icons",
  321. Inventory: "inventory",
  322. JobPoints: "jobpoints",
  323. Medals: "medals",
  324. Merits: "merits",
  325. Messages: "messages",
  326. Money: "money",
  327. Networth: "networth",
  328. Notifications: "notifications",
  329. Perks: "perks",
  330. PersonalStats: "personalstats",
  331. Profile: "profile",
  332. Properties: "properties",
  333. ReceivedEvents: "receivedevents",
  334. Refills: "refills",
  335. Revives: "revives",
  336. RevivesFull: "revivesfull",
  337. Stocks: "stocks",
  338. Timestamp: "timestamp",
  339. Travel: "travel",
  340. WeaponExp: "weaponexp",
  341. WorkStats: "workstats"
  342. }
  343. },
  344. Properties: {
  345. Key: "property",
  346. Selections: null
  347. },
  348. Faction: {
  349. Key: "faction",
  350. Selections: null
  351. },
  352. Company: {
  353. Key: "company",
  354. Selections: null
  355. },
  356. ItemMarket: {
  357. Key: "market",
  358. Selections: null
  359. },
  360. Torn: {
  361. Key: "torn",
  362. Selections: null
  363. }
  364. }
  365.  
  366. function tornAPIRequest(part, selections, key) {
  367. let funcName = "tornAPIRequest";
  368.  
  369. createDebugLog(thisScriptName, funcName, `Torn API request for Part: ${part} Player Id: ${tornPlayerId} Selections: ${selections}`);
  370. if (validateEmpty(key)) {
  371. key = tornAPIKey;
  372. }
  373.  
  374. return new Promise((resolve, reject) => {
  375.  
  376. GM_xmlhttpRequest({
  377. method: "GET",
  378. url: `https://api.torn.com/${part}/${tornPlayerId}?selections=${selections}&key=${key}`,
  379. onreadystatechange: function(response) {
  380. if (response.readyState > 3 && response.status === 200) {
  381. createDebugLog(thisScriptName, funcName, "Torn API response received: ")
  382. logDebugObject(response);
  383. let verifyJSON = verifyJSONString(response.responseText);
  384. createDebugLog(thisScriptName, funcName, "Torn API Json verify response:");
  385. logDebugObject(verifyJSON);
  386. if (verifyJSON.isError) {
  387. createDebugLog(thisScriptName, funcName, "JSON Error: " + verifyJSON.errorName + " - " + verifyJSON.errorMessage + " ResponseText: " + response.responseText);
  388. reject("JSON Error", response.responseText);
  389. return;
  390. }
  391.  
  392. resolve(verifyJSON.content);
  393.  
  394. if (verifyJSON.content.error) {
  395. createDebugLog(thisScriptName, funcName, "Torn API Error: " + verifyJSON.content.error.code)
  396. if (verifyJSON.content.error.code == 2) {
  397. clearAPIKey();
  398. }
  399. }
  400. }
  401. },
  402. onerror: function(errorResponse) {
  403. createDebugLog(thisScriptName, funcName, "httpRequest Error: " + errorResponse);
  404. reject('httpRequest error.');
  405. }
  406. })
  407. }).catch(err => {
  408. createDebugLog(thisScriptName, funcName, "Promise Error: " + err);
  409. });
  410. }
  411.  
  412. //#endregion Torn API
  413.  
  414. //#region Generic API
  415.  
  416. function genericAPIRequest(destUrl, requestMethod) {
  417. let funcName = "genericAPIRequest";
  418.  
  419. createDebugLog(thisScriptName, funcName, `API request to ${destUrl}`);
  420.  
  421. return new Promise((resolve, reject) => {
  422. GM_xmlhttpRequest({
  423. method: requestMethod,
  424. url: destUrl,
  425. headers: {'Cookie': document.cookie},
  426. onload: function (respData) {
  427. console.log('*****GET Resp')
  428. logDebugObject(respData);
  429.  
  430. //TODO: Parse response properly and send back at least the status code as well
  431.  
  432. resolve(respData.responseText);
  433. },
  434. onerror: function(errorResponse) {
  435. console.log('*****GET Error', errorResponse);
  436. reject('httpRequest error.');
  437. }
  438. })
  439. }).catch(err => {
  440. createDebugLog(thisScriptName, funcName, "Promise Error: " + err);
  441. });
  442. }
  443.  
  444. //#endregion Generic API
  445.  
  446.  
  447. //#region Cookies
  448.  
  449. function getCookie(cname) {
  450. var name = cname + "=";
  451. var ca = document.cookie.split(';');
  452. for(var i = 0; i < ca.length; i++) {
  453. var c = ca[i];
  454. while (c.charAt(0) == ' ') {
  455. c = c.substring(1);
  456. }
  457. if (c.indexOf(name) == 0) {
  458. return c.substring(name.length, c.length);
  459. }
  460. }
  461. return "";
  462. }
  463.  
  464. //#endregion