// ==UserScript== // @author DanielOnDiordna // @name IITC plugin: Favorite portal details // @category Info // @version 0.1.6.20210724.002500 // @updateURL https://softspot.nl/ingress/plugins/iitc-plugin-favorite-portal-details.meta.js // @downloadURL https://softspot.nl/ingress/plugins/iitc-plugin-favorite-portal-details.user.js // @description [danielondiordna-0.1.6.20210724.002500] Quickly show a list of details for your favorite list of portals. // @id iitc-plugin-favorite-portal-details@danielondiordna // @namespace https://softspot.nl/ingress/ // @match https://intel.ingress.com/* // @grant none // ==/UserScript== function wrapper(plugin_info) { // ensure plugin framework is there, even if iitc is not yet loaded if(typeof window.plugin !== 'function') window.plugin = function() {}; // use own namespace for plugin window.plugin.favoriteportaldetails = function() {}; var self = window.plugin.favoriteportaldetails; self.id = 'favoriteportaldetails'; self.title = 'Favorite portal details'; self.version = '0.1.6.20210724.002500'; self.author = 'DanielOnDiordna'; self.changelog = ` Changelog: version 0.1.1.20180911.233100 - earlier version version 0.1.1.20181030.221200 - bug fix: localstoragesettings was not defined version 0.1.2.20190117.143900 - minor code fix: assign needs empty array version 0.1.3.20190406.225100 - bug fix: resonators and mods object converted to array for sort purposes - support for empty mods - underline resos and mods also if the active player is not the owner - sort resos by level and then by owner name version 0.1.4.20190530.122000 - closedialog fix for smartphone version 0.1.5.20210123.230400 - updated plugin wrapper and userscript header formatting to match IITC-CE coding - store portal titles for later use - fixed width of dialog version 0.1.6.20210328.235400 - fixed portal guid format checker version 0.1.6.20210421.190200 - minor fix for IITC CE where runHooks iitcLoaded is executed before addHook is defined in this plugin version 0.1.6.20210724.002500 - prevent double plugin setup on hook iitcLoaded `; self.namespace = 'window.plugin.' + self.id + '.'; self.pluginname = 'plugin-' + self.id; self.panename = 'plugin-' + self.id; self.localstoragesettings = self.panename + '-settings'; self.dialogobject = null; self.onPortalSelectedPending = false; self.settings = { refreshonstart: true }; self.favoriteslist = []; self.favorites = {}; self.favorite = { title: '', team: '?', level: '?', resonators: [], mods: [], health: '?', owner: '?', timestamp: 0, lat: 0.0, lng: 0.0 }; self.storagename = self.panename + '-favorites'; // self.selector = '
'; self.selector = ''; self.requestlist = {}; self.requestrunning = false; self.requestguid = null; self.requesttimerid = 0; self.ownercolor = 'black'; self.refreshonload_runonce = true; self.shortnames = { '' :' ', 'Heat Sink' :'H', 'Portal Shield' :'S', 'Link Amp' :'L', 'Turret' :'T', 'Multi-hack' :'M', 'Aegis Shield' :'A', 'Force Amp' :'F', 'SoftBank Ultra Link' :'U', 'Ito En Transmuter (+)':'I+', 'Ito En Transmuter (-)':'I-' }; self.shortrarities = { '' :' ', 'COMMON' :'c', 'RARE' :'r', 'VERY_RARE':'v' }; self.restoresettings = function() { if (typeof localStorage[self.localstoragesettings] === 'string') { var settings = JSON.parse(localStorage[self.localstoragesettings]); if (typeof settings === 'object' && settings instanceof Object) { if (typeof settings.refreshonstart === 'boolean') self.settings.refreshonstart = settings.refreshonstart; } } }; self.storesettings = function() { localStorage[self.localstoragesettings] = JSON.stringify(self.settings); }; self.restorefavorites = function() { if (typeof localStorage[self.storagename] === 'string') { var favoriteslist = JSON.parse(localStorage[self.storagename]); // array of separator names and guid=>portal name (or guid only) self.favoriteslist = []; // array of separator names and guids self.favorites = {}; // hash of guid=>{portal details} for (var cnt = 0; cnt < favoriteslist.length; cnt++) { if (typeof favoriteslist[cnt] === 'string' && favoriteslist[cnt].match(/^[0-9a-f]{32}\.[0-9a-f]{2}$/)) { // old file format: in case it's only a guid, convert to new formatting let guid = favoriteslist[cnt]; let favorite = {}; favorite[guid] = guid; // use guid as portal name favoriteslist[cnt] = favorite; } if (typeof favoriteslist[cnt] === 'object' && favoriteslist[cnt] instanceof Object) { let guid = Object.keys(favoriteslist[cnt])[0]; self.favorites[guid] = Object.assign({}, self.favorite); // copy empty favoritee object without reference self.favorites[guid].title = favoriteslist[cnt][guid]; self.favoriteslist.push(guid); } else if (typeof favoriteslist[cnt] === 'string') { // separator name self.favoriteslist.push(favoriteslist[cnt]); } } } }; self.storefavorites = function() { let storedata = []; // array of separator names and guid=>portal name for (let cnt = 0; cnt < self.favoriteslist.length; cnt++) { if (self.favoriteslist[cnt].match(/^[0-9a-f]{32}\.[0-9a-f]{2}$/)) { // guid let guid = self.favoriteslist[cnt]; let favorite = {}; favorite[guid] = self.favorites[guid].title; storedata.push(favorite); } else { // separator name storedata.push(self.favoriteslist[cnt]); } } localStorage[self.storagename] = JSON.stringify(storedata); }; self.requesttimeout = function() { self.requestrunning = false; self.requestlist = {}; self.updateselector(); }; self.requestnext = function() { if (Object.keys(self.requestlist).length === 0) { self.requestrunning = false; return; } var guid = Object.keys(self.requestlist)[0]; self.requestguid = guid; window.setTimeout(function() { self.requesttimerid = window.setTimeout(self.requesttimeout,10000); // 10 seconds window.portalDetail.request(self.requestguid); },1000); // keep a second between request }; self.requestall = function() { if (self.requestrunning) return; if (Object.keys(window.portals).length === 0) return; self.requestrunning = true; for (var guid in self.favorites) { self.requestlist[guid] = true; } self.requestnext(); }; self.focusportal = function(guid) { if (Object.keys(window.portals).length === 0) return; // cancel while no portals loaded yet; prevents an error inside the IITC core if (window.selectedPortal === guid && self.favorites[guid]) { map.setView([self.favorites[guid].lat,self.favorites[guid].lng]); } if (window.portals[guid]) { window.renderPortalDetails(guid); } else { self.requestguid = guid; window.portalDetail.request(guid); } }; self.closedialog = function() { if (self.dialogobject) { self.dialogobject.dialog('close'); self.dialogobject = null; } }; self.getdatetimestring = function(date1) { if (!(date1 instanceof Date)) { if (date1) { date1 = new Date(date1); } else { date1 = new Date(); } } return [date1.getFullYear(),date1.getMonth()+1,date1.getDate()].join('/') + ' ' + [date1.getHours(),('0' + date1.getMinutes()).slice(-2),('0' + date1.getSeconds()).slice(-2)].join(':'); }; self.resonatorshtml = function(resonators,portalowner) { var highlightowner = window.PLAYER.nickname; var resolist = []; resonators = resonators.sort( function(a,b) { if (a.level < b.level) return 1; if (a.level > b.level) return -1; let o1 = a.owner.toLowerCase(); let o2 = b.owner.toLowerCase(); if (o1 > o2) return 1; if (o1 < o2) return -1; return 0; }); // sort by resonator level and then by owner for (var cnt = 0; cnt < 8; cnt++) { var lvl = '-'; if (cnt < resonators.length && resonators[cnt]) { // {owner, level, energy} var resonatorowner = resonators[cnt].owner; lvl = resonators[cnt].level; if (resonatorowner === highlightowner) { lvl = '' + lvl + ''; // highlight reso's of current player } if (resonatorowner !== portalowner) { lvl = '' + lvl + ''; // underline reso's of other people then the portal owner } lvl = '' + lvl + ''; } resolist.push(lvl); } return resolist.join(''); }; self.modshtml = function(mods,portalowner) { var highlightowner = window.PLAYER.nickname; var modslist = []; for (var cnt = 0; cnt < mods.length; cnt++) { // {owner, name, rarity, stats: {…}} var mod; if (!mods[cnt]) { mod = ''; } else { mod = self.shortnames[mods[cnt].name]; if (mod === 'H' || mod === 'S' || mod === 'M') mod = self.shortrarities[mods[cnt].rarity] + mod; var modowner = mods[cnt].owner; if (modowner === highlightowner) { mod = '' + mod + ''; // highlight mods of current player } if (modowner !== portalowner) { mod = '' + mod + ''; // underline mods of other people then the portal owner } mod = '' + mod + ''; } modslist.push(mod); } return modslist.join(' '); }; self.favoriteshtml = function() { var highlightowner = window.PLAYER.nickname; var rows = []; var headers = []; headers.push('T'); headers.push('Title'); headers.push('Health'); headers.push('Lvl'); headers.push('Resonators'); headers.push('Mods'); headers.push('Owner'); headers.push('Checked'); rows.push('