Last active
August 2, 2019 10:30
-
-
Save Eccenux/8e0460dc89124bc3f19b to your computer and use it in GitHub Desktop.
This is a uniques plugin fork which assists you in hunting keys from certain area. Effectively allows to tick a portal for which you have a key. Switch to "keyhunt" highlighter (included in this plugin) to show in red which keys you are still missing (in orange will be portals for which you haven't entered data yet). Use 'sync' plugin to share d…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @id iitc-plugin-keyhunt-keys@3ch01c | |
// @name IITC plugin: keyhunt-keys | |
// @category Misc | |
// @version 0.0.3.20160405.143600 | |
// @namespace https://github.com/3ch01c/ingress-intel-total-conversion | |
// @description This is a plugin which assists you in hunting keys from certain area. Effectively allows to tick a portal for which you have a key. Switch to "keyhunt" highlighter (included in this plugin) to show in red which keys you are still missing (the portal for which you haven't entered data yet will be orange, other will be green). Use 'sync' plugin to share data between multiple browsers or desktop/mobile. Use keyhunt plugin with 'portals-list' plugin to quickly tick many portals on a list. | |
// @include https://www.ingress.com/intel* | |
// @include http://www.ingress.com/intel* | |
// @match https://www.ingress.com/intel* | |
// @match http://www.ingress.com/intel* | |
// @include https://www.ingress.com/mission/* | |
// @include http://www.ingress.com/mission/* | |
// @match https://www.ingress.com/mission/* | |
// @match http://www.ingress.com/mission/* | |
// @grant none | |
// ==/UserScript== | |
/** | |
Authorship note. | |
This is a uniques plugin fork see: | |
https://github.com/jonatkins/ingress-intel-total-conversion/blob/master/plugins/uniques.user.js | |
Author of this fork is Maciej Nux Jaros. | |
*/ | |
/** | |
Hacks/notes | |
// number of portals/keys marked (true/false) | |
Object.keys(window.plugin.keyhunt.keyhunt).length | |
// detailed count | |
var counts = { | |
'captured' : 0, | |
'total' : 0 | |
}; | |
$.each(window.plugin.keyhunt.keyhunt, function(){ | |
if (this.keycaptured) { | |
counts.captured++; | |
} | |
counts.total++; | |
}); | |
console.dir(counts); | |
*/ | |
function wrapper(plugin_info) { | |
// ensure plugin framework is there, even if iitc is not yet loaded | |
if(typeof window.plugin !== 'function') window.plugin = function() {}; | |
/* | |
//PLUGIN AUTHORS: writing a plugin outside of the IITC build environment? if so, delete these lines!! | |
//(leaving them in place might break the 'About IITC' page or break update checks) | |
plugin_info.buildName = 'nux'; | |
plugin_info.dateTimeVersion = '20160325.150303'; | |
plugin_info.pluginId = 'keyhunt_keys'; | |
//END PLUGIN AUTHORS NOTE | |
*/ | |
//PLUGIN START //////////////////////////////////////////////////////// | |
//use own namespace for plugin | |
window.plugin.keyhunt = function() {}; | |
//delay in ms | |
window.plugin.keyhunt.SYNC_DELAY = 5000; | |
// maps the JS property names to localStorage keys | |
window.plugin.keyhunt.FIELDS = { | |
'keyhunt': 'plugin-keyhunt-data', | |
'updateQueue': 'plugin-keyhunt-data-queue', | |
'updatingQueue': 'plugin-keyhunt-data-updating-queue', | |
}; | |
window.plugin.keyhunt.keyhunt = {}; | |
window.plugin.keyhunt.updateQueue = {}; | |
window.plugin.keyhunt.updatingQueue = {}; | |
window.plugin.keyhunt.enableSync = false; | |
window.plugin.keyhunt.disabledMessage = null; | |
window.plugin.keyhunt.contentHTML = null; | |
window.plugin.keyhunt.isHighlightActive = false; | |
window.plugin.keyhunt.onPortalDetailsUpdated = function() { | |
if(typeof(Storage) === "undefined") { | |
$('#portaldetails > .imgpreview').after(plugin.keyhunt.disabledMessage); | |
return; | |
} | |
var guid = window.selectedPortal, | |
details = portalDetail.get(guid), | |
nickname = window.PLAYER.nickname; | |
$('#portaldetails > .imgpreview').after(plugin.keyhunt.contentHTML); | |
plugin.keyhunt.updateCheckedAndHighlight(guid); | |
} | |
window.plugin.keyhunt.updateCheckedAndHighlight = function(guid) { | |
runHooks('pluginkeyhuntUpdatekeyhunt', { guid: guid }); | |
if (guid == window.selectedPortal) { | |
var uniqueInfo = plugin.keyhunt.keyhunt[guid], | |
keycaptured = (uniqueInfo && uniqueInfo.keycaptured) || false; | |
$('#keycaptured').prop('checked', keycaptured); | |
} | |
if (window.plugin.keyhunt.isHighlightActive) { | |
if (portals[guid]) { | |
window.setMarkerStyle (portals[guid], guid == selectedPortal); | |
} | |
} | |
} | |
window.plugin.keyhunt.setPortalCaptured = function(guid) { | |
plugin.keyhunt.keyhunt[guid] = { | |
keycaptured: true | |
}; | |
plugin.keyhunt.updateCheckedAndHighlight(guid); | |
plugin.keyhunt.sync(guid); | |
} | |
window.plugin.keyhunt.updateCaptured = function(keycaptured, guid) { | |
if(guid == undefined) guid = window.selectedPortal; | |
console.log('updateCaptured(',keycaptured,', ',guid,')'); | |
if(guid in plugin.keyhunt.keyhunt | |
&& keycaptured === plugin.keyhunt.keyhunt[guid].keycaptured) { | |
console.log('no changes'); | |
return; | |
} | |
// creating new object because otherwise changes won't work after sync. | |
plugin.keyhunt.keyhunt[guid] = { | |
keycaptured: keycaptured ? true : false | |
}; | |
plugin.keyhunt.updateCheckedAndHighlight(guid); | |
plugin.keyhunt.sync(guid); | |
} | |
// stores the gived GUID for sync | |
plugin.keyhunt.sync = function(guid) { | |
plugin.keyhunt.updateQueue[guid] = true; | |
plugin.keyhunt.storeLocal('keyhunt'); | |
plugin.keyhunt.storeLocal('updateQueue'); | |
plugin.keyhunt.syncQueue(); | |
} | |
// sync the queue, but delay the actual sync to group a few updates in a single request | |
window.plugin.keyhunt.syncQueue = function() { | |
if(!plugin.keyhunt.enableSync) return; | |
clearTimeout(plugin.keyhunt.syncTimer); | |
plugin.keyhunt.syncTimer = setTimeout(function() { | |
plugin.keyhunt.syncTimer = null; | |
$.extend(plugin.keyhunt.updatingQueue, plugin.keyhunt.updateQueue); | |
plugin.keyhunt.updateQueue = {}; | |
plugin.keyhunt.storeLocal('updatingQueue'); | |
plugin.keyhunt.storeLocal('updateQueue'); | |
plugin.sync.updateMap('keyhunt', 'keyhunt', Object.keys(plugin.keyhunt.updatingQueue)); | |
}, plugin.keyhunt.SYNC_DELAY); | |
} | |
//Call after IITC and all plugin loaded | |
window.plugin.keyhunt.registerFieldForSyncing = function() { | |
if(!window.plugin.sync) return; | |
window.plugin.sync.registerMapForSync('keyhunt', 'keyhunt', window.plugin.keyhunt.syncCallback, window.plugin.keyhunt.syncInitialed); | |
} | |
//Call after local or remote change uploaded | |
window.plugin.keyhunt.syncCallback = function(pluginName, fieldName, e, fullUpdated) { | |
if(fieldName === 'keyhunt') { | |
plugin.keyhunt.storeLocal('keyhunt'); | |
// All data is replaced if other client update the data during this client | |
// offline, | |
// fire 'pluginkeyhuntRefreshAll' to notify a full update | |
if(fullUpdated) { | |
// a full update - update the selected portal sidebar | |
if (window.selectedPortal) { | |
plugin.keyhunt.updateCheckedAndHighlight(window.selectedPortal); | |
} | |
// and also update all highlights, if needed | |
if (window.plugin.keyhunt.isHighlightActive) { | |
resetHighlightedPortals(); | |
} | |
window.runHooks('pluginkeyhuntRefreshAll'); | |
return; | |
} | |
if(!e) return; | |
if(e.isLocal) { | |
// Update pushed successfully, remove it from updatingQueue | |
delete plugin.keyhunt.updatingQueue[e.property]; | |
} else { | |
// Remote update | |
delete plugin.keyhunt.updateQueue[e.property]; | |
plugin.keyhunt.storeLocal('updateQueue'); | |
plugin.keyhunt.updateCheckedAndHighlight(e.property); | |
window.runHooks('pluginkeyhuntUpdatekeyhunt', {guid: e.property}); | |
} | |
} | |
} | |
//syncing of the field is initialed, upload all queued update | |
window.plugin.keyhunt.syncInitialed = function(pluginName, fieldName) { | |
if(fieldName === 'keyhunt') { | |
plugin.keyhunt.enableSync = true; | |
if(Object.keys(plugin.keyhunt.updateQueue).length > 0) { | |
plugin.keyhunt.syncQueue(); | |
} | |
} | |
} | |
window.plugin.keyhunt.storeLocal = function(name) { | |
var key = window.plugin.keyhunt.FIELDS[name]; | |
if(key === undefined) return; | |
var value = plugin.keyhunt[name]; | |
if(typeof value !== 'undefined' && value !== null) { | |
localStorage[key] = JSON.stringify(plugin.keyhunt[name]); | |
} else { | |
localStorage.removeItem(key); | |
} | |
} | |
window.plugin.keyhunt.loadLocal = function(name) { | |
var key = window.plugin.keyhunt.FIELDS[name]; | |
if(key === undefined) return; | |
if(localStorage[key] !== undefined) { | |
plugin.keyhunt[name] = JSON.parse(localStorage[key]); | |
} | |
} | |
/***************************************************************************************************************************************************************/ | |
/** HIGHLIGHTER ************************************************************************************************************************************************/ | |
/***************************************************************************************************************************************************************/ | |
window.plugin.keyhunt.highlighter = { | |
highlight: function(data) { | |
var guid = data.portal.options.ent[0]; | |
var uniqueInfo = window.plugin.keyhunt.keyhunt[guid]; | |
var style = {}; | |
style.fillOpacity = 0.7; | |
if (uniqueInfo) { | |
if (uniqueInfo.keycaptured) { | |
// key captured | |
style.fillColor = 'green'; | |
} else { | |
// key is not captured | |
style.fillColor = 'red'; | |
} | |
} else { | |
// no data at all | |
style.fillColor = 'orange'; | |
} | |
data.portal.setStyle(style); | |
}, | |
setSelected: function(active) { | |
window.plugin.keyhunt.isHighlightActive = active; | |
} | |
} | |
window.plugin.keyhunt.setupCSS = function() { | |
$("<style>") | |
.prop("type", "text/css") | |
.html("#keyhunt-container {\n display: block;\n text-align: center;\n margin: 6px 3px 1px 3px;\n padding: 0 4px;\n}\n#keyhunt-container label {\n margin: 0 0.5em;\n}\n#keyhunt-container input {\n vertical-align: middle;\n}\n\n.portal-list-keyhunt input[type=\'checkbox\'] {\n padding: 0;\n height: auto;\n margin-top: -5px;\n margin-bottom: -5px;\n}\n") | |
.appendTo("head"); | |
} | |
window.plugin.keyhunt.setupContent = function() { | |
plugin.keyhunt.contentHTML = '<div id="keyhunt-container">' | |
+ '<label><input type="checkbox" id="keycaptured" onclick="window.plugin.keyhunt.updateCaptured($(this).prop(\'checked\'))"> Key captured</label>' | |
+ '</div>'; | |
plugin.keyhunt.disabledMessage = '<div id="keyhunt-container" class="help" title="Your browser does not support localStorage">Plugin keyhunt disabled</div>'; | |
} | |
window.plugin.keyhunt.setupPortalsList = function() { | |
if(!window.plugin.portalslist) return; | |
window.addHook('pluginkeyhuntUpdatekeyhunt', function(data) { | |
var info = plugin.keyhunt.keyhunt[data.guid]; | |
if(!info) info = { keycaptured: false }; | |
$('[data-list-keyhunt="'+data.guid+'"].keycaptured').prop('checked', !!info.keycaptured); | |
}); | |
window.addHook('pluginkeyhuntRefreshAll', function() { | |
$('[data-list-keyhunt]').each(function(i, element) { | |
var guid = element.getAttribute("data-list-keyhunt"); | |
var info = plugin.keyhunt.keyhunt[guid]; | |
if(!info) info = { keycaptured: false }; | |
var e = $(element); | |
if(e.hasClass('keycaptured')) e.prop('checked', !!info.keycaptured); | |
}); | |
}); | |
function uniqueValue(guid) { | |
var info = plugin.keyhunt.keyhunt[guid]; | |
if(!info) return 0; | |
if(info.keycaptured) return 1; | |
return 2; | |
} | |
window.plugin.portalslist.fields.push({ | |
title: "Key hunt", | |
value: function(portal) { return portal.options.guid; }, // we store the guid, but implement a custom comparator so the list does sort properly without closing and reopening the dialog | |
sort: function(guidA, guidB) { | |
return uniqueValue(guidA) - uniqueValue(guidB); | |
}, | |
format: function(cell, portal, guid) { | |
var info = plugin.keyhunt.keyhunt[guid]; | |
if(!info) info = { keycaptured: false }; | |
$(cell).addClass("portal-list-keyhunt"); | |
// for some reason, jQuery removes event listeners when the list is sorted. Therefore we use DOM's addEventListener | |
$('<input>') | |
.prop({ | |
type: "checkbox", | |
className: "keycaptured", | |
title: "Portal keycaptured?", | |
checked: !!info.keycaptured, | |
}) | |
.attr("data-list-keyhunt", guid) | |
.appendTo(cell) | |
[0].addEventListener("change", function(ev) { | |
window.plugin.keyhunt.updateCaptured(this.checked, guid); | |
ev.preventDefault(); | |
return false; | |
}, false); | |
}, | |
}); | |
} | |
var setup = function() { | |
window.pluginCreateHook('pluginkeyhuntUpdatekeyhunt'); | |
window.pluginCreateHook('pluginkeyhuntRefreshAll'); | |
window.plugin.keyhunt.setupCSS(); | |
window.plugin.keyhunt.setupContent(); | |
window.plugin.keyhunt.loadLocal('keyhunt'); | |
window.addPortalHighlighter('keyhunt', window.plugin.keyhunt.highlighter); | |
window.addHook('portalDetailsUpdated', window.plugin.keyhunt.onPortalDetailsUpdated); | |
window.addHook('iitcLoaded', window.plugin.keyhunt.registerFieldForSyncing); | |
if(window.plugin.portalslist) { | |
window.plugin.keyhunt.setupPortalsList(); | |
} else { | |
setTimeout(function() { | |
if(window.plugin.portalslist) | |
window.plugin.keyhunt.setupPortalsList(); | |
}, 500); | |
} | |
} | |
//PLUGIN END ////////////////////////////////////////////////////////// | |
setup.info = plugin_info; //add the script info data to the function as a property | |
if(!window.bootPlugins) window.bootPlugins = []; | |
window.bootPlugins.push(setup); | |
// if IITC has already booted, immediately run the 'setup' function | |
if(window.iitcLoaded && typeof setup === 'function') setup(); | |
} // wrapper end | |
// inject code into site context | |
var script = document.createElement('script'); | |
var info = {}; | |
if (typeof GM_info !== 'undefined' && GM_info && GM_info.script) info.script = { version: GM_info.script.version, name: GM_info.script.name, description: GM_info.script.description }; | |
script.appendChild(document.createTextNode('('+ wrapper +')('+JSON.stringify(info)+');')); | |
(document.body || document.head || document.documentElement).appendChild(script); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Installation
Mobile
To install plugin on your phone:
Obviously you need IITC mobile on your phone first.
Desktop
To install plugin on your desktop:
Obviously you need to have IITC in your desktop browser first.