NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name InkMods // @license MIT // @copyright 2017, Lex_The_Great (https://openuserjs.org/users/Lex_The_Great) // @namespace https://www.reddit.com/r/inkarnate/ // @updateURL https://openuserjs.org/meta/Lex_The_Great/InkMods.meta.js // @version 1.6 // @description Inkarnate Mods! // @author Lex_The_Great // @include http*://*/maps* // @require http://code.jquery.com/jquery-latest.js // @require https://openuserjs.org/src/libs/sizzle/GM_config.js // @require https://gist.githubusercontent.com/PizzaBrandon/5709010/raw/e539a6f16c10465eb948b9ef6b0fe1d4c17a7c3e/jquery.waituntilexists.js // @grant GM_getValue // @grant GM_setValue // @grant GM_webRequest // @grant GM_xmlhttpRequest // @grant GM_addStyle // @run-at document-start // ==/UserScript== // Some reason /^(.*)\/maps\#\/(.*)$/ doesn't work so we will use *.... var ImageBank = { Storage: [], // ["imageurl", imagedata] load: function () { window.ImageBank.Storage = gmGet("ImageBank", []); console.log("Load Storage"); }, save: function () { gmSet("ImageBank", this.Storage); console.log("Save Storage"); }, add: function(url, data) { window.ImageBank.Storage.push([url,data]); console.log("Saved Image In Storage: ", url); }, contains: function(url) { for(var i = 0; i < this.Storage.length; i++) { var itemObject = window.ImageBank.Storage[i]; // [0] url, [1] data if (itemObject[0] == url) { return i; } } return false; }, get: function(url) { var ObjectId = window.ImageBank.contains(url); if (ObjectId != false) { console.log("Load From Storage: ", url); return this.Storage[ObjectId][1]; } else { console.log("Saved to storage: ", url); var image = new Image(); image.crossOrigin = "anonymous"; image.onload = function () { var canvas = document.createElement('canvas'); canvas.width = this.naturalWidth; // or 'width' if you want a special/scaled size canvas.height = this.naturalHeight; // or 'height' if you want a special/scaled size canvas.getContext('2d').drawImage(this, 0, 0); window.ImageBank.add(url,canvas.toDataURL('image/png')); }; image.src = url; return url; } } }; window.ImageBank = ImageBank; function gmGet(name) { var theValue = GM_getValue(name); return theValue; } function gmSet(name, valuee) { GM_setValue(name, valuee); } unsafeWindow.saveImageBank = function() { console.log("Saved Image Bank!") gmSet("ImageBank", ImageBank.Storage); } //unsafeWindow.ImageBankObject = cloneInto (ImageBank, unsafeWindow, {cloneFunctions: true}); unsafeWindow.Image.prototype.hijack = function (url) { /*if (url.search("ocean-1") > 0) { console.log("Found background."); if (localStorage.getItem("BackgroundImage") !== null && localStorage.getItem("BackgroundImage") !== '') { this.src = localStorage.getItem("BackgroundImage"); console.log("Hijacked Background: " + url); } } else if (url.search("ct-") > 0) { this.src = url; } else { this.src = window.ImageBank.get(url); }*/ this.src = window.ImageBank.get(url); }; function isFireFox() { //Check if browser is Firefox or not if (navigator.userAgent.search("Firefox") >= 0) return true; return false; } function injectScript(text) { var newScript = document.createElement('script'); newScript.type = "text/javascript"; newScript.textContent = text; var head = document.getElementsByTagName('head')[0]; head.appendChild(newScript); } function injectMods(text) { // Inject MapSize Editor text = text.replace(/!function\(t,e\){/g, 'var xsize=1024;var ysize=768;if(localStorage.getItem("mapX")!==undefined&&localStorage.getItem("mapY")!==undefined){console.log("Debug:Settingsize:"+xsize+":"+ysize);xsize=localStorage.getItem("mapX");ysize=localStorage.getItem("mapY");}window.constX=xsize;window.constY=ysize;!function(t,e){'); text = text.replace(/width:e,height:i,/g, 'width:constX,height:constY,'); //text = text.replace(/this\.w=1024\*this\.s\.map\.scale,this\.h=1024\*this\.s\.map\.scale,/g, 'this.w=constX*this.s.map.scale,this.h=constY*this.s.map.scale,'); //text = text.replace(/width:t\.map\.width\*t\.map\.scale,height:t\.map\.height\*t\.map\.scale/g, 'width:constX*t.map.scale,height:constY*t.map.scale'); //text = text.replace(/e.attr\(\{width:1024\*t\.map\.scale,height:1024\*t\.map\.scale}\),/g, 'e.attr({width:constX*t.map.scale,height:constY*t.map.scale}),'); //text = text.replace(/"fantasy-world",1024,768/g, '"fantasy-world",constX,constY'); // Comercial Support text = text.replace(/1024,768/g, 'constX,constY'); //text = text.replace(/1024/g, 'constX'); // ImageHijack if (localStorage.getItem("QuickLoad") == 'true') { console.log("quickload") text = text.replace(/s\.src=n,/g, 's.hijack(n),'); text = text.replace(/console\.log\(\"skin loaded\"\)\,/g, 'console.log("skin loaded"),window.saveImageBank(),'); } /* Debug text = text.replace(/console\.log\("loaded",e\)/g, 'console.log("loaded",e,i)'); text = text.replace(/console\.log\("loading",e\)/g, 'console.log("loading",e,i)'); text = text.replace(/console\.log\("texture load",n\)/g, 'console.log("texture load",n,s)'); text = text.replace(/console\.log\("texture loaded",n\)/g, 'console.log("texture loaded",n,s)'); */ // Todo something else usefull.. injectScript(text); } var InkMods = { Config: false, ConfigOpen: false, Button: $('<div id="InkModsMenu">Settings</div>'), init: function () { this.Config = GM_config.init({ 'id': 'Inkarnate', 'fields': { 'Init': { 'label': 'Init (Hidden)', 'type': 'checkbox', 'default': false }, 'LargeMode': { 'label': 'Move around UI to work with Large Maps. (Will break Map Selection Menu!)<br>', 'type': 'checkbox', 'default': false }, 'QuickLoad': { 'label': 'Quick Load/Save Images (After first load, is faster) Uncheck to clear storage!<br>', 'type': 'checkbox', 'default': false }, 'MapX': { 'label': 'Map Width (When creating new map.)<br>', 'type': 'int', 'min': 1024, 'default': 1024 }, 'MapY': { 'label': 'Map Height (When creating new map.)<br>', 'type': 'int', 'min': 768, 'default': 768 }, 'BackgroundImage': { 'label': 'Background Image, Blank for defualt. (When creating new map.) *NotWorking for now*<br>', 'type': 'text', 'default': '' } }, 'events': { 'init': function () { window.InkMods.onInit(this); }, 'open': function () { console.log('onOpen()'); }, 'save': function () { window.InkMods.onSave(this); }, 'close': function () { window.InkMods.onClose(this); }, 'reset': function () { window.InkMods.setupStorage(this, true); console.log('onReset()'); } }, 'css': '#Inkarnate_Init_var { display: none !important; }' }); }, setupStorage: function (cfg, reset) { console.log("InkMods: Init Storage."); if (!cfg.get("Init") || reset === true || GM_info.script.version !== localStorage.getItem("Version")) { console.log("InkMods: New Storage."); cfg.set("Init", true); cfg.save(); localStorage.setItem("Version", GM_info.script.version); localStorage.setItem("LargeMode", false); localStorage.setItem("QuickLoad", false); localStorage.setItem("mapX", 1024); localStorage.setItem("mapY", 768); localStorage.setItem("BackgroundImage", ''); } window.ImageBank.load(); }, onInit: function (cfg) { this.setupStorage(cfg); console.log('onInit()'); this.Button.css({ "position": "fixed", "right": "100px", "bottom": "10px", "border": "1px solid #6b5326", "padding": "5px 10px", "color": "orange", "cursor": "pointer", "z-index": "99999" }); this.Button.insertAfter("#fb-root"); var p = this; this.Button.click(function () { if (p.ConfigOpen) return; p.ConfigOpen = true; cfg.open(); }); }, onClose: function (cfg) { console.log('onClose()'); this.ConfigOpen = false; }, onSave: function (cfg) { console.log('onSave()'); this.Options.MapSize(cfg.get("MapX"), cfg.get("MapY")); this.Options.BackgroundImage(cfg.get("BackgroundImage")); this.Options.LargeMode(cfg.get("LargeMode")); this.Options.QuickLoad(cfg.get("QuickLoad")); }, Options: { MapSize: function (x, y) { if (typeof x === 'number' && isFinite(x) && typeof y === 'number' && isFinite(y)) { localStorage.setItem("mapX", x); localStorage.setItem("mapY", y); constX = x; constY = y; } }, BackgroundImage: function (url) { localStorage.setItem("BackgroundImage", url); }, QuickLoad: function (flag) { localStorage.setItem("QuickLoad", flag); if (flag) { // Reload the page? } else { window.ImageBank.storage = []; window.ImageBank.save(); } }, LargeMode: function (flag) { localStorage.setItem("LargeMode", flag); if (flag && this.style === undefined) { console.log("Injected Styles."); this.style = GM_addStyle('#map-builder-view { position: absolute; }' + '.map-builder-container { position: absolute; width: auto; left: 80px;}' + '#left-sidebar, #tool-options, #logo-menu, #selected-tool { position: fixed; z-index: 999;}' + '#tool-options, #selected-tool { left: 22%;}' + '#logo-menu { left: 1px; top: 20px;}' + '#left-sidebar { left: 10px; top: 15%;}'); } else if (!flag && this.style !== undefined) { this.style.remove(); this.style = undefined; } } } }; function doMenu() { $(window).load(function (e) { if (typeof (Storage) !== "undefined") { console.log("InkMods: Init"); window.InkMods = InkMods; window.InkMods.init(); window.InkMods.Options.LargeMode((localStorage.getItem("LargeMode") == 'true')); } else { console.log("InkMods: Error, Storage is undefined."); } if (!$("#logo-menu").length) { console.log("InkMods: Debug: Can't find #logo-menu. (Page loaded to fast?) " + $("#logo-menu").length); return; } $("#ui").waitUntilExists(function (e) { $("#map-container > canvas").css({ width: constX + 'px', height: constY + 'px' }); }); $("#objects > ul").waitUntilExists(function (e) { $("#objects > ul").css({ overflow: 'scroll' }); }); $("#textures > ul").waitUntilExists(function (e) { $("#textures > ul").css({ overflow: 'scroll' }); }); }); } window.doMenu = doMenu; if (isFireFox()) { console.log("Mozzila!"); window.addEventListener('beforescriptexecute', function (e) { src = e.target.src; if (src.search(/map-builder-app(.*)\.js/) != -1) { e.preventDefault(); e.stopPropagation(); console.log("Block: " + e.target.src); window.mapjs = e.target.src; GM_xmlhttpRequest({ method: "GET", url: window.mapjs, synchronous: true, onload: function (response) { console.log("Hijacked: " + window.mapjs); injectMods(response.responseText); GM_xmlhttpRequest({ method: "GET", url: "https://ajax.googleapis.com/ajax/libs/angularjs/1.2.28/angular-route.js", onload: function (response) { console.log("Hijacked: " + e.target.src); injectScript(response.responseText); window.doMenu(); } }); } }); } if (src.search(/angular-route(.*)\.js/) != -1) { e.preventDefault(); e.stopPropagation(); } }); } else { console.log("Something else?"); alert("You're not using firefox. Chrome doesn't have beforescriptexecute."); // Going to need to edit this file your self if you have crhome. Chrome doesn't have a working interceptor :( basicly replaces are above. Host on your own local server. Do not redistrubute inkarnate! // Also, put in userscript above for chrome! // @webRequest [{"selector":"*/assets/map-builder-app*.js","action":{"redirect":"https://localhost/map-builder-app.js"}}] GM_webRequest([{ selector: '*/assets/map-builder-app*.js', action: { redirect: 'https://localhost/map-builder-app.js' } }, ], function (info, message, details) { console.log(info, message, details); }); }