您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Commonly used functions in my Torn scripts.
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/392610/751012/DKK%20Torn%20Utilities%20DEVELOPMENT.js
- // ==UserScript==
- // @name DKK Torn Utilities DEVELOPMENT
- // @description Commonly used functions in my Torn scripts.
- // @version 2.0.5
- // @exclude *
- // @namespace https://openuserjs.org/users/DeKleineKobini
- // @homepageURL https://www.torn.com/forums.php#/p=threads&t=16110079
- // ==/UserScript==
- /* Script Setup */
- loadCSS();
- addFunctions();
- function loadCSS() {
- if ($("#dkkutilscss").length) return;
- $("head").append("<style id='dkkutilscss'>"
- + ".dkk-widget { margin-top: 10px; }"
- + ".dkk-widget_red, .dkk-widget_green { background-image: linear-gradient(90deg, transparent 50%, rgba(0, 0, 0, 0.07) 0px); background-size: 4px; display: flex; align-items: center; color: rgb(255, 255, 255); font-size: 13px; letter-spacing: 1px; text-shadow: rgba(0, 0, 0, 0.65) 1px 1px 2px; padding: 6px 10px; border-radius: 5px 5px 0 0; } "
- + ".dkk-widget_green { background-color: rgb(144, 176, 46); }"
- + ".dkk-widget_red { background-color: rgb(251, 0, 25); }"
- + ".dkk-widget_title { flex-grow: 1; box-sizing: border-box; }"
- + ".dkk-widget_body { display: flex; padding: 0px; line-height: 1.4; background-color: rgb(242, 242, 242); }"
- + ".dkk-widget-bottom { border-radius: 0 0 10px 10px; }"
- + ".dkk-panel-left, .dkk-panel-right, .dkk-panel-middle { flex: 1 0 0px; max-height: 120px; overflow: auto; min-height: 60px; }"
- + ".dkk-panel-left { border-left: 1px solid transparent; }"
- + ".dkk-panel-middle { display: flex-direction: column; }"
- + ".dkk-panel-right { display: flex-direction: column; border-radius: 0 0 5px 5px; }"
- + ".dkk-data-table { width: 100%; height: 100%; border-collapse: separate; text-align: left; }"
- + ".dkk-data-table > tbody > tr > th { height: 16px; white-space: nowrap; text-overflow: ellipsis; font-weight: 700; padding: 2px 10px; border-top: 1px solid rgb(255, 255, 255); border-bottom: 1px solid rgb(204, 204, 204); background: linear-gradient(rgb(255, 255, 255), rgb(215, 205, 220)); }"
- + ".dkk-data-table > tbody > tr > td { padding: 2px 10px; border-top: 1px solid rgb(255, 255, 255); border-right: 1px solid rgb(204, 204, 204); border-bottom: 1px solid rgb(204, 204, 204); }"
- + "</style>"
- );
- }
- function addFunctions() {
- // formating for numbers
- Number.prototype.format = function(n, x) {
- var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\.' : '$') + ')';
- return this.toFixed(Math.max(0, ~~n)).replace(new RegExp(re, 'g'), '$&,');
- };
- // string functions
- String.prototype.replaceAll = function(text, replace) {
- let str = this.toString();
- while (str.includes(text)) { str = str.replace(text, replace); }
- return str;
- };
- }
- function initScript(options) {
- // some easy name conversion
- if (options.name) {
- if (!options.id) options.id = options.name.replaceAll(" ", "").toLowerCase();
- if (!options.abbr) options.abbr = "";
- }
- if (!options.logging) {
- options.logging = "WARN";
- }
- // actually init
- if (options.api){
- if (options.apikey) _setAPI(options.apikey);
- requireAPI();
- }
- if (!unsafeWindow.scripts) unsafeWindow.scripts = { ids: [] };
- unsafeWindow.scripts.ids.push(options.id);
- unsafeWindow.scripts[options.id] = {
- name: options.name,
- abbr: options.abbr,
- api: options.api ? true : false
- };
- dkklog.level = options.logging;
- dkklog.prefix = "[" + options.abbr + "]";
- }
- /* Messaging */
- class DKKLog {
- constructor(prefix, level) {
- this.levels = {
- FATAL: 0,
- ERROR: 1,
- WARN: 2,
- INFO: 3,
- DEBUG: 4,
- TRACE: 5,
- ALL: 6,
- OFF: 7
- },
- this.prefix = prefix;
- this._level = level || 2;
- }
- get level() {
- return this._level;
- }
- set level(val) {
- this._level = this.levels[val];
- }
- logging(level, message, objs) {
- if (this._level< this.levels[level]) return;
- let msg = `${this.prefix}[${level}] ${message}`;
- if (objs && objs.length) console.log(msg, ...objs);
- else console.log(msg);
- }
- fatal(message, ...objs) { this.logging("FATAL", message, objs); }
- error(message, ...objs) { this.logging("ERROR", message, objs); }
- warn(message, ...objs) { this.logging("WARN", message, objs); }
- info(message, ...objs) { this.logging("INFO", message, objs); }
- debug(message, ...objs) { this.logging("DEBUG", message, objs); }
- trace(message, ...objs) { this.logging("TRACE", message, objs); }
- all(message, ...objs) { this.logging("ALL", message, objs); }
- }
- var dkklog = new DKKLog("[DKK]", 3);
- /* Torn API */
- class TornAPI {
- constructor(callback) {
- this.key = localStorage.getItem("dkkutils_apikey");
- if (!this.isValid()) {
- dkklog.trace("Asking for the api key.");
- let createPrompt = () => {
- $(".content-wrapper > .content-title").after(
- "<div><article class='dkk-widget' style='display: none;'><header class='dkk-widget_green'><span class='dkk-widget_title'>${name}</span></header>"
- + "<div class='dkk-widget_body'>"
- + "<div class='dkk-panel-left'><table class='dkk-data-table'><tr><th class='dkk-data-table_header'>Item Information</th></tr><tr><td class='dkk-data-table_cell'><table class='dkk-information-table'><tr><td class='dkk-data-table_cell'>Items Found</td><td class='dkk-data-table_cell' id='ct19-itemcount'>loading...</td></tr><tr><td class='dkk-data-table_cell'>Total Value</td><td class='dkk-data-table_cell' id='ct19-itemvalue'>loading...</td></tr><tr><td class='dkk-data-table_cell'>Average Value</td><td class='dkk-data-table_cell' id='ct19-itemvalueavg'>loading...</td></tr></table></td></tr></table></div>"
- + "<div class='dkk-panel-middle'></div>"
- + "<div class='dkk-panel-right'></div>"
- + "</div>"
- + "</article></div><div class='clear'></div>"
- );
- }
- if ($(".content-wrapper").length) createPrompt();
- else observeMutations(document, ".content-wrapper", true, createPromt, { childList: true, subtree: true });
- } else {
- callback();
- }
- }
- isValid() {
- if (!this.key || this.key === undefined || this.key == "undefined" || this.key === null || this.key == "null" || this.key === "") return false;
- return true;
- }
- }
- unsafeWindow.TornAPI = TornAPI;
- var apiKey;
- const API_LENGTH = 16;
- const STORAGE_LOCATION = "dkkutils_apikey";
- function requireAPI() {
- dkklog.debug("Require API")
- apiKey = getAPI();
- if (!_isValidAPIKey(apiKey)) {
- dkklog.debug("Require API - no valid api found")
- let response = prompt("Please enter your API key: ");
- if (_isValidAPIKey(response)) {
- setAPI(response);
- } else {
- dkklog.debug("Require API - no valid api given")
- alert("Given API key was not valid, script might not work.\nRefresh to try again.")
- }
- }
- }
- function _isValidAPIKey(key) {
- if (!key) key = apiKey;
- if (!key || key === undefined || key == "undefined" || key === null || key == "null" || key === "") return false;
- if (key.length != API_LENGTH) return false;
- return true;
- }
- function sendAPIRequest(part, id, selections, key) {
- dkklog.debug(`Sending API request to ${part}/${selections} on id ${id}`);
- if (!key) key = apiKey;
- return new Promise((resolve, reject) => {
- GM_xmlhttpRequest({
- method: "GET",
- url: `https://api.torn.com/${part}/${id}?selections=${selections}&key=${key}`,
- onreadystatechange: function(res) {
- if (res.readyState > 3 && res.status === 200) {
- dkklog.debug("API response received.")
- if (!isJsonString(res.responseText)) {
- reject("JSON Error", res.responseText);
- return;
- }
- var json = JSON.parse(res.responseText);
- resolve(json);
- if (json.error) {
- var code = json.error.code;
- dkklog.debug("API Error: " + code)
- if (code == 2) setAPI(null);
- }
- }
- },
- onerror: function(err) {
- console.log(err);
- reject('XHR error.');
- }
- })
- }).catch(e => {
- console.log(e);
- });
- }
- function setAPI(key) {
- if (!_isValidAPIKey(key)) {
- localStorage.removeItem(STORAGE_LOCATION);
- dkklog.debug("Removed key from storage.")
- } else {
- localStorage.setItem(STORAGE_LOCATION, key);
- dkklog.debug(`Added key '${key}' to storage. '${localStorage.getItem(STORAGE_LOCATION)}'`)
- }
- apiKey = key;
- }
- function _setAPI(key) {
- if (!_isValidAPIKey(key)) localStorage.removeItem(STORAGE_LOCATION);
- else localStorage.setItem(STORAGE_LOCATION, key);
- apiKey = key;
- }
- function getAPI() {
- let utilsKey = localStorage.getItem(STORAGE_LOCATION);
- if (_isValidAPIKey(utilsKey)) {
- dkklog.debug("getAPI - from own storage '" + utilsKey.length + "'");
- return utilsKey;
- } else {
- dkklog.debug("getAPI - from own storage is invalid '" + utilsKey + "'");
- }
- let key = localStorage.getItem("_apiKey") || localStorage.getItem("x_apikey") || localStorage.getItem("jebster.torn") || localStorage.getItem("TornApiKey");
- if (_isValidAPIKey(key)) {
- dkklog.debug("getAPI - from other storage");
- setAPI(key);
- } else if (localStorage.getItem("_apiKey")) {
- dkklog.debug("getAPI - removed 1");
- localStorage.removeItem("_apiKey");
- } else if (localStorage.getItem("x_apikey")) {
- dkklog.debug("getAPI - removed 2");
- localStorage.removeItem("x_apikey");
- } else if (localStorage.getItem("jebster.torn")) {
- dkklog.debug("getAPI - removed 3");
- localStorage.removeItem("jebster.torn");
- } else if (localStorage.getItem("_apiKey")) {
- dkklog.debug("getAPI - removed 4");
- localStorage.removeItem("TornApiKey");
- }
- return utilsKey;
- }
- /* Torn General*/
- function getScriptUser() {
- let body = $("body")
- let contentWrapper = $("#mainContainer > .content-wrapper");
- return {
- isJailed: body.hasClass("jail"),
- isHospitalized: body.hasClass("hospital"),
- isTravelling: contentWrapper.hasClass("travelling")
- }
- }
- /* Networking */
- function xhrIntercept(callback) {
- let oldXHROpen = window.XMLHttpRequest.prototype.open;
- window.XMLHttpRequest.prototype.open = function() {
- this.addEventListener('readystatechange', function() {
- if (this.readyState > 3 && this.status == 200) {
- var page = this.responseURL.substring(this.responseURL.indexOf("torn.com/") + "torn.com/".length, this.responseURL.indexOf(".php"));
- var json, uri;
- if (isJsonString(this.response)) json = JSON.parse(this.response);
- else uri = getUrlParams(this.responseURL);
- callback(page, json, uri, this);
- }
- });
- return oldXHROpen.apply(this, arguments);
- }
- }
- function ajax(callback) {
- $(document).ajaxComplete((event, xhr, settings) => {
- if (xhr.readyState > 3 && xhr.status == 200) {
- if (settings.url.indexOf("torn.com/") < 0) settings.url = "torn.com" + (settings.url.startsWith("/") ? "" : "/") + settings.url;
- var page = settings.url.substring(settings.url.indexOf("torn.com/") + "torn.com/".length, settings.url.indexOf(".php"));
- var json, uri;
- if (isJsonString(xhr.responseText)) json = JSON.parse(xhr.responseText);
- else uri = getUrlParams(settings.url);
- callback(page, json, uri, xhr, settings);
- }
- });
- }
- function interceptFetch(url, callback) {
- unsafeWindow.fetch = async (input, options) => {
- const response = await fetch(input, options)
- if (response.url.startsWith("https://www.torn.com/" + url)) {
- let res = response.clone();
- Promise.resolve(res.json().then((json) => callback(json, res.url)));
- }
- return response;
- }
- }
- /* DOM */
- function observeMutationsFull(root, callback, options) {
- if (!options) options = {
- childList: true
- };
- new MutationObserver(callback).observe(root, options);
- }
- function observeMutations(root, selector, runOnce, callback, options, callbackRemoval) {
- var ran = false;
- observeMutationsFull(root, function(mutations, me) {
- var check = $(selector);
- if (check.length) {
- if (runOnce) me.disconnect();
- ran = true;
- callback(mutations, me);
- } else if (ran) {
- ran = false;
- if (callbackRemoval) callbackRemoval(mutations, me);
- }
- }, options);
- }
- /* Caching */
- function setCache(key, value, time, sub) {
- var end = time == -1 ? -1 : Date.now() + time;
- var obj = sub ? value : {
- value: value,
- end: Date.now() + time
- };
- GM_setValue(key, JSON.stringify(obj));
- }
- async function getCache(key, subbed) {
- let _obj = await GM_getValue(key, subbed ? "{}" : "{\"end\":0}");
- let obj = JSON.parse(_obj);
- var end = obj.end;
- if (!end || end == -1 || end > Date.now())
- return subbed ? obj : obj.value;
- return undefined;
- }
- function getSubCache(cache, id) {
- if (cache[id]) {
- var end = cache[id].end;
- if (end == -1 || end > Date.now())
- return cache[id].value;
- }
- return undefined;
- }
- /* General Utilities */
- function isJsonString(str) {
- if (!str || str == "") return false;
- try {
- JSON.parse(str);
- } catch (e) {
- return false;
- }
- return true;
- }
- /**
- * JavaScript Get URL Parameter (https://www.kevinleary.net/javascript-get-url-parameters/)
- *
- * @param String prop The specific URL parameter you want to retreive the value for
- * @return String|Object If prop is provided a string value is returned, otherwise an object of all properties is returned
- */
- function getUrlParams(url, prop) {
- var params = {};
- var search = decodeURIComponent(((url) ? url : window.location.href).slice(window.location.href.indexOf('?') + 1));
- var definitions = search.split('&');
- definitions.forEach(function(val, key) {
- var parts = val.split('=', 2);
- params[parts[0]] = parts[1];
- });
- return (prop && prop in params) ? params[prop] : params;
- }
- function getSpecialSearch() {
- let hash = window.location.hash;
- hash = hash.replace("#/", "?");
- hash = hash.replace("#!", "?");
- return hash;
- }
- function stripHtml(html) {
- var tmp = document.createElement("DIV");
- tmp.innerHTML = html;
- var stripped = tmp.textContent || tmp.innerText || "";
- stripped = stripped.replaceAll("\n", "");
- stripped = stripped.replaceAll("\t", "");
- stripped = stripped.replaceAll(" ", " ");
- return stripped;
- }
- function getNewDay() {
- let now = new Date();
- let newDay = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate() - 1, 0, 0, 0));
- if (Date.now() >= newDay.getTime()) newDay.setUTCDate(newDay.getUTCDate() + 1);
- if (Date.now() >= newDay.getTime()) newDay.setUTCDate(newDay.getUTCDate() + 1);
- return newDay;
- }
- function getMillisUntilNewDay() {
- return getNewDay().getTime() - Date.now();
- }
- function _isMobile() {
- return navigator.userAgent.match(/Android/i) ||
- navigator.userAgent.match(/webOS/i) ||
- navigator.userAgent.match(/iPhone/i) ||
- navigator.userAgent.match(/iPad/i) ||
- navigator.userAgent.match(/iPod/i) ||
- navigator.userAgent.match(/BlackBerry/i) ||
- navigator.userAgent.match(/Windows Phone/i);
- }
- function runOnEvent(funct, event, runBefore) {
- if (runBefore) funct();
- $(window).bind(event, function() {
- funct();
- });
- }
- function timeSince(timeStamp) {
- let now = new Date();
- let secondsPast = (now.getTime() - timeStamp.getTime()) / 1000;
- if (secondsPast < 60) return parseInt(secondsPast) + 's';
- else if (secondsPast < 3600) return parseInt(secondsPast / 60) + 'm';
- else if (secondsPast <= 86400) return parseInt(secondsPast / 3600) + 'h';
- else if (secondsPast > 86400) {
- let day = timeStamp.getDate();
- let month = timeStamp.toDateString().match(/ [a-zA-Z]*/)[0].replace(" ", "");
- let year = timeStamp.getFullYear() == now.getFullYear() ? "" : " " + timeStamp.getFullYear();
- return day + " " + month + year;
- }
- }