Skip to content

Instantly share code, notes, and snippets.

@Eccenux
Last active August 2, 2019 10:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Eccenux/8e0460dc89124bc3f19b to your computer and use it in GitHub Desktop.
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…
// ==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);
@Eccenux
Copy link
Author

Eccenux commented Apr 2, 2016

Installation

Mobile

To install plugin on your phone:

  1. Open URL on your phone: https://gist.github.com/Eccenux/8e0460dc89124bc3f19b/raw/iitc-plugin-keyhunt.user.js?v0.0.3
  2. Open in "IITC Plugin".

Obviously you need IITC mobile on your phone first.

Desktop

To install plugin on your desktop:

  1. Open this page
  2. Click on "Raw" button.
  3. Install plugin (installation form should appear automatically).

Obviously you need to have IITC in your desktop browser first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment