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);
});
}