From f6246f840c406547170ad49f739ae12d849a06f8 Mon Sep 17 00:00:00 2001 From: imsaguy Date: Tue, 31 Mar 2015 15:33:11 -0500 Subject: [PATCH 01/45] Basic style edits This is just to cleanup the code to follow proper coding styles. --- plugins/score-cycle-times.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/score-cycle-times.user.js b/plugins/score-cycle-times.user.js index bf9a6530..c2f11de0 100644 --- a/plugins/score-cycle-times.user.js +++ b/plugins/score-cycle-times.user.js @@ -60,7 +60,7 @@ window.plugin.scoreCycleTimes.update = function() { timeStr = timeStr.replace(/:00$/,''); //FIXME: doesn't remove seconds from AM/PM formatted dates return ''+label+''+timeStr+''; - } + }; var html = '' + formatRow('Cycle start', cycleStart) @@ -72,7 +72,7 @@ window.plugin.scoreCycleTimes.update = function() { $('#score_cycle_times_display').html(html); setTimeout ( window.plugin.scoreCycleTimes.update, checkpointEnd-now); -} +}; From c6750a261542e885b4338e0efd6c204b8da31e89 Mon Sep 17 00:00:00 2001 From: Joseph Verburg Date: Fri, 3 Apr 2015 14:12:10 +0200 Subject: [PATCH 02/45] Full mission support, uses proper requests and data to provide a mission interface just like the normal intel map. There are a few extras: - Mark finished/visited waypoints. - Mark finished missions. - Allow event hooks :). - Show portal status(level and health) --- plugins/missions.user.js | 660 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 640 insertions(+), 20 deletions(-) diff --git a/plugins/missions.user.js b/plugins/missions.user.js index 97b94a4b..aa76a29a 100644 --- a/plugins/missions.user.js +++ b/plugins/missions.user.js @@ -2,11 +2,11 @@ // @id iitc-plugin-missions@jonatkins // @name IITC plugin: Missions // @category Info -// @version 0.0.1.@@DATETIMEVERSION@@ +// @version 0.0.2.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] WORK IN PROGRESS: view missions. Currently, only adds a mission start portal highlighter +// @description [@@BUILDNAME@@-@@BUILDDATE@@] View missions. Marking progress on waypoints/missions basis. Showing mission paths on the map. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* @@ -19,33 +19,653 @@ // PLUGIN START //////////////////////////////////////////////////////// -// use own namespace for plugin -window.plugin.missions = function() {}; +var decodeWaypoint = function(data) { + var result = { + hidden: data[0], + guid: data[1], + title: data[2], + typeNum: data[3], + type: [null, "Portal", "Field Trip"][data[3]], + objectiveNum: data[4], + objective: [null, "Hack this Portal", "Capture or Upgrade Portal", "Create Link from Portal", "Create Field from Portal", "Install a Mod on this Portal", "Take a Photo", "View this Field Trip Waypoint", "Enter the Passphrase"][data[4]], + }; + if (result.typeNum === 1) { + result.portal = window.decodeArray.portalSummary(data[5]); + // Portal waypoints have the same guid as the respective portal. + result.portal.guid = result.guid; + } + return result; +}; +var decodeMission = function(data) { + return { + guid: data[0], + title: data[1], + description: data[2], + authorNickname: data[3], + authorTeam: data[4], + // Notice: this format is weird(100%: 1.000.000) + ratingE6: data[5], + medianCompletionTimeMs: data[6], + numUniqueCompletedPlayers: data[7], + typeNum: data[8], + type: [null, "Sequential", "Non Sequential", "Hidden"][data[8]], + waypoints: data[9].map(decodeWaypoint), + image: data[10] + }; +}; +var decodeMissionSummary = function(data) { + return { + guid: data[0], + title: data[1], + image: data[2], + ratingE6: data[3], + medianCompletionTimeMs: data[4] + }; +}; +var timeToRemaining = function(t) { + var data = parseInt(t / 86400) + 'd ' + (new Date(t % 86400 * 1000)).toUTCString().replace(/.*(\d{2}):(\d{2}):(\d{2}).*/, "$1h $2m $3s"); + data = data.replace('0d', ''); + data = data.replace('00h', ''); + data = data.replace('00m', ''); + return data.trim(); +}; +window.plugin.missions = { + // 3 days. + missionCacheTime: 3 * 24 * 3600 * 1E3, + // 3 weeks. + portalMissionsCacheTime: 21 * 24 * 3600 * 1E3, + onPortalSelected: function(event) { + /*if(event.selectedPortalGuid === event.unselectedPortalGuid) { + return; + }*/ + if (window.selectedPortal === null) { + return; + } + var portal = window.portals[window.selectedPortal]; + if (!portal || (!portal.options.data.mission && !portal.options.data.mission50plus)) { + return; + } + // After select. + setTimeout(function() { + // #resodetails + $('.linkdetails').append('Open mission(s)'); + }, 0); + }, -window.plugin.missions.highlight = function(data) { - var opacity = 0.7; - var color = undefined; + openTopMissions: function(bounds) { + bounds = bounds || window.map.getBounds(); + this.loadMissionsInBounds(bounds, this.showMissionListDialog.bind(this)); + }, - if (data.portal.options.data.mission50plus) { - color='red'; - } else if (data.portal.options.data.mission) { - color='darkorange'; - } + openPortalMissions: function() { + var me = this, + portal = window.portals[window.selectedPortal]; + if (!portal) { + return; + } + this.loadPortalMissions(window.selectedPortal, function(missions) { + if (!missions.length) { + return; + } - if (color) { - data.portal.setStyle({fillColor: color, fillOpacity: opacity}); - } -} + if (missions.length === 1) { + me.loadMission(missions[0].guid, me.showMissionDialog.bind(me)); + } else { + me.showMissionListDialog(missions); + } + }); + }, -window.plugin.missions.setup = function() { + openMission: function(guid) { + this.loadMission(guid, this.showMissionDialog.bind(this)); + }, - window.addPortalHighlighter('Mission start point', window.plugin.missions.highlight); + showMissionDialog: function(mission) { + var me = this; + var markers = this.highlightMissionPortals(mission); + dialog({ + // id: 'mission-' + mission.guid, + title: mission.title, + height: 'auto', + html: this.renderMission(mission), + width: '450px', + closeCallback: function() { + me.unhighlightMissionPortals(markers); + }, + collapseCallback: this.collapsFix, + expandCallback: this.collapsFix + }); + }, + showMissionListDialog: function(missions) { + dialog({ + html: this.renderMissionList(missions), + height: 'auto', + width: '400px', + collapseCallback: this.collapsFix, + expandCallback: this.collapsFix + }); + }, + + collapsFix: function() { + if (this && this.parentNode) { + this.parentNode.style.height = 'auto'; + } + }, + + loadMissionsInBounds: function(bounds, callback, errorcallback) { + var me = this; + window.postAjax('getTopMissionsInBounds', { + northE6: ((bounds.getNorth() * 1000000) | 0), + southE6: ((bounds.getSouth() * 1000000) | 0), + westE6: ((bounds.getWest() * 1000000) | 0), + eastE6: ((bounds.getEast() * 1000000) | 0) + }, function(data) { + var missions = data.result.map(decodeMissionSummary); + if (!missions) { + if (errorcallback) { + errorcallback('Invalid data'); + } + return; + } + callback(missions); + }, function(error) { + console.log('Error loading missions in bounds', arguments); + if (errorcallback) { + errorcallback(error); + } + }); + }, + + loadPortalMissions: function(guid, callback, errorcallback) { + var me = this; + // Mission summary rarely goes stale. + if (me.cacheByPortalGuid[guid] && this.cacheByPortalGuid[guid].time > (Date.now() - this.portalMissionsCacheTime)) { + callback(me.cacheByPortalGuid[guid].data); + return; + } + window.postAjax('getTopMissionsForPortal', { + guid: window.selectedPortal + }, function(data) { + var missions = data.result.map(decodeMissionSummary); + if (!missions) { + if (errorcallback) { + errorcallback('Invalid data'); + } + return; + } + + window.runHooks('portalMissionsLoaded', { missions: missions, portalguid: guid }); + + me.cacheByPortalGuid[guid] = { + time: Date.now(), + data: missions + }; + me.saveData(); + callback(missions); + }, function(error) { + console.log('Error loading portal missions', arguments); + if (errorcallback) { + errorcallback(error); + } + // awww + }); + }, + loadMission: function(guid, callback, errorcallback) { + var me = this; + // TODO: we need to refresh data often enough, portal data can quickly go stale + if (this.cacheByMissionGuid[guid] && this.cacheByMissionGuid[guid].time > (Date.now() - this.missionCacheTime)) { + callback(this.getMissionCache(guid, true)); + return; + } + window.postAjax('getMissionDetails', { + guid: guid + }, function(data) { + var mission = decodeMission(data.result); + if (!mission) { + if (errorcallback) { + errorcallback('Invalid data'); + } + return; + } + + window.runHooks('missionLoaded', { mission: mission }); + + me.cacheByMissionGuid[guid] = { + time: Date.now(), + data: mission + }; + me.saveData(); + + callback(mission); + }, function() { + console.log('Error loading mission data', guid, arguments); + if (errorcallback) { + errorcallback(error); + } + // awww + }); + }, + + renderMissionList: function(missions) { + return missions.map(this.renderMissionSummary, this).join(' '); + }, + + renderMissionSummary: function(mission) { + var cachedMission = this.getMissionCache(mission.guid); + + var html = ''; + var checked = this.settings.checkedMissions[mission.guid]; + + html += '
'; + html += ''; + html += '
' + mission.title + '
'; + if (cachedMission) { + html += '' + cachedMission.authorNickname + ''; + html += '
'; + } + html += '' + + timeToRemaining((mission.medianCompletionTimeMs / 1000) | 0); + html += '' + + (((mission.ratingE6 / 100) | 0) / 100) + '%'; + + if (cachedMission) { + html += '' + + cachedMission.numUniqueCompletedPlayers; + html += '' + + cachedMission.waypoints.length; + } + html += '
'; + html += '
'; + return html; + }, + + renderMission: function(mission) { + var me = this; + var checked = this.settings.checkedMissions[mission.guid]; + //commondatastorage.googleapis.com/ingress.com/img/map_icons/linkmodeicon.png + var html = '
'; + html += ''; + html += ''; + html += ''; + html += ''; + html += '
' + mission.title + '
'; + html += '' + mission.authorNickname + ''; + html += '
'; + html += '
'; + html += '' + + timeToRemaining((mission.medianCompletionTimeMs / 1000) | 0); + html += '' + + (((mission.ratingE6 / 100) | 0) / 100) + '%'; + html += '' + + mission.numUniqueCompletedPlayers; + html += '' + + mission.waypoints.length; + html += '
'; + html += '

'; + html += mission.description; + html += '

'; + html += '
'; + html += mission.waypoints.map(function(waypoint, index) { + return me.renderMissionWaypoint(waypoint, index, mission); + }).join(' '); + return html; + }, + + renderMissionWaypoint: function(waypoint, index, mission) { + var html = ''; + html += '

'; + html += '

'; + if (waypoint.portal) { + var color = 'white'; + if (waypoint.portal.team === 'R') { // Yay + color = '#00c2ff'; + } else if (waypoint.portal.team === 'E') { // Booo + color = '#28f428'; + } + var realHealth = (waypoint.portal.resCount / 8) * (waypoint.portal.health / 100); + html += this.renderPortalCircle(color, waypoint.portal.level, realHealth); + /* + var radius = ((realHealth * 360) | 0); + html += '
'; + html += '
'; + html += '
'; // 360 + 45 + html += '
' + waypoint.portal.level + '
'; + html += '
'; + */ + } + if (waypoint.portal) { + html += ''; + } + if (waypoint.title) { + html += waypoint.title; + } else { + html += 'Unknown'; + } + if (waypoint.portal) { + html += ''; + } + html += '
'; + /* + checkbox_grey + checkbox_orange + checkbox_cyan + */ + var img = 'cyan'; + if (index === 0) { + img = 'orange'; + } else if (!waypoint.objective) { + img = 'grey'; + } + // ✓ + var mwpid = mission.guid + '-' + waypoint.guid; + var checked = this.settings.checkedWaypoints[mwpid]; + + html += ''; + html += ''; + + html += ''; + html += ''; + html += (waypoint.objective ? waypoint.objective : '?'); + html += '

'; + return html; + }, + renderPortalCircle: function(portalColor, portalLevel, portalHealth) { + var s = 20, + bg = '#999', + c = portalColor, + i = 14, + ic = '#555', + s2 = ((s / 2) | 0), + si = (((s - i) / 2) | 0), + d = (portalHealth * 180) | 0, + num = portalLevel; + var html = '
'; + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += '
' + num; + html += '
'; + html += '
'; + return html; + }, + + toggleWaypoint: function(mid, wpid, dontsave) { + var mwpid = mid + '-' + wpid; + var el = document.getElementsByClassName('wp-' + mwpid); + if (!this.settings.checkedWaypoints[mwpid]) { + this.settings.checkedWaypoints[mwpid] = true; + window.runHooks('waypointFinished', { mission: this.getMissionCache(mid), waypointguid: wpid }); + $(el).show(); + } else { + delete this.settings.checkedWaypoints[mwpid]; + $(el).hide(); + } + if (!dontsave) { + this.saveData(); + } + }, + + toggleMission: function(mid) { + var mission = this.getMissionCache(mid); + if (!mission) { + return; + } + var el = document.getElementsByClassName('m-' + mid); + var sumel = document.getElementsByClassName('mc-' + mid); + if (!this.settings.checkedMissions[mid]) { + this.settings.checkedMissions[mid] = true; + mission.waypoints.forEach(function(waypoint) { + if (!this.settings.checkedWaypoints[mid + '-' + waypoint.guid]) { + this.toggleWaypoint(mid, waypoint.guid, true); + } + }, this); + $(el).show(); + $(sumel).css('background-color', 'rgba(255, 187, 0, 0.3)'); + window.runHooks('missionFinished', { mission: mission }); + } else { + delete this.settings.checkedMissions[mid]; + mission.waypoints.forEach(function(waypoint) { + if (this.settings.checkedWaypoints[mid + '-' + waypoint.guid]) { + this.toggleWaypoint(mid, waypoint.guid, true); + } + }, this); + $(el).hide(); + $(sumel).css('background-color', ''); + } + this.saveData(); + }, + + getMissionCache: function(guid, updatePortals) { + if (this.cacheByMissionGuid[guid]) { + var cache = this.cacheByMissionGuid[guid]; + // Update portal data from map if older then 2 minutes. + if (updatePortals && cache.time < (Date.now() - (2 * 60 * 1000))) { + cache.data.waypoints.map(function(waypoint) { + if (!waypoint.portal) { + return; + } + var wp = window.portals[waypoint.portal.guid]; + if (!wp) { + return; + } + $.extend(waypoint.portal, wp.options.data); + }); + } + return cache.data; + } + return null; + }, + + getPortalCache: function(guid) { + if (this.cacheByPortalGuid[guid]) { + return this.cacheByPortalGuid[guid].data; + } + return null; + }, + + saveData: function() { + this.checkCacheSize(); + localStorage['plugins-missions-portalcache'] = JSON.stringify(this.cacheByPortalGuid); + localStorage['plugins-missions-missioncache'] = JSON.stringify(this.cacheByMissionGuid); + localStorage['plugins-missions-settings'] = JSON.stringify(this.settings); + }, + + loadData: function() { + this.cacheByPortalGuid = JSON.parse(localStorage['plugins-missions-portalcache'] || '{}'); + this.cacheByMissionGuid = JSON.parse(localStorage['plugins-missions-missioncache'] || '{}'); + this.settings = JSON.parse(localStorage['plugins-missions-settings'] || '{}'); + }, + + checkCacheSize: function() { + if (JSON.stringify(this.cacheByPortalGuid).length > 1e6) { // 1 MB not MiB ;) + this.cleanupPortalCache(); + } + if (JSON.stringify(this.cacheByMissionGuid).length > 2e6) { // 2 MB not MiB ;) + this.cleanupMissionCache(); + } + }, + + // Cleanup oldest half of the data. + cleanupPortalCache: function() { + var me = this; + var cache = Object.keys(this.cacheByPortalGuid); + cache.sort(function(a, b) { + return me.cacheByPortalGuid[a].time - me.cacheByPortalGuid[b].time; + }); + var toDelete = (cache.length / 2) | 0; + cache.splice(0, toDelete + 1).forEach(function(el) { + delete me.cacheByPortalGuid[el]; + }); + }, + + // Cleanup oldest half of the data. + cleanupMissionCache: function() { + var me = this; + var cache = Object.keys(this.cacheByMissionGuid); + cache.sort(function(a, b) { + return me.cacheByMissionGuid[a].time - me.cacheByMissionGuid[b].time; + }); + var toDelete = (cache.length / 2) | 0; + cache.splice(0, toDelete + 1).forEach(function(el) { + delete me.cacheByMissionGuid[el]; + }); + }, + + highlightMissionPortals: function(mission) { + var markers = []; + var prevPortal = null; + mission.waypoints.forEach(function(waypoint) { + if (!waypoint.portal) { + return; + } + var portal = window.portals[waypoint.portal.guid]; + if (!portal) { // not in view? + return; + } + var marker = L.circleMarker( + L.latLng(portal.options.data.latE6 / 1E6, portal.options.data.lngE6 / 1E6), { + radius: portal.options.radius + Math.ceil(portal.options.radius / 2), + weight: 3, + opacity: 1, + color: '#222', + fill: false, + dashArray: null, + clickable: false + } + ); + this.missionLayer.addLayer(marker); + markers.push(marker); + if (prevPortal) { + var line = L.geodesicPolyline([ + L.latLng(prevPortal.options.data.latE6 / 1E6, prevPortal.options.data.lngE6 / 1E6), + L.latLng(portal.options.data.latE6 / 1E6, portal.options.data.lngE6 / 1E6) + ], { + color: '#222', + + opacity: 1, + weight: 2, + clickable: false + }); + this.missionLayer.addLayer(line); + markers.push(line); + } + prevPortal = portal; + }, this); + return markers; + }, + + unhighlightMissionPortals: function(markers) { + markers.forEach(function(marker) { + this.missionLayer.removeLayer(marker); + }, this); + }, + + onPortalChanged: function(type, guid, oldval) { + var portal; + if (type === 'add' || type === 'update') { + // Compatibility + portal = window.portals[guid] || oldval; + if (!portal.options.data.mission && !portal.options.data.mission50plus) { + return; + } + if (this.markedStarterPortals[guid]) { + return; + } + + this.markedStarterPortals[guid] = L.circleMarker( + L.latLng(portal.options.data.latE6 / 1E6, portal.options.data.lngE6 / 1E6), { + radius: portal.options.radius + Math.ceil(portal.options.radius / 2), + weight: 3, + opacity: 1, + color: '#555', + fill: false, + dashArray: null, + clickable: false + } + ); + this.missionStartLayer.addLayer(this.markedStarterPortals[guid]); + } else if (type === 'delete') { + portal = oldval; + if (!this.markedStarterPortals[guid]) { + return; + } + + this.missionStartLayer.removeLayer(this.markedStarterPortals[guid]); + delete this.markedStarterPortals[guid]; + } + }, + + setup: function() { + this.cacheByPortalGuid = {}; + this.cacheByMissionGuid = {}; + + this.markedStarterPortals = {}; + this.markedMissionPortals = {}; + + this.loadData(); + + if (!this.settings.checkedWaypoints) { + this.settings.checkedWaypoints = {}; + } + if (!this.settings.checkedMissions) { + this.settings.checkedMissions = {}; + } + + $('#toolbox').append('Open mission(s) in window'); + + // window.addPortalHighlighter('Mission start point', this.highlight.bind(this)); + window.addHook('portalSelected', this.onPortalSelected.bind(this)); + + /* + I know iitc has portalAdded event but it is missing portalDeleted. So we have to resort to Object.observe + */ + var me = this; + if (Object.observe) { // Chrome + Object.observe(window.portals, function(changes) { + changes.forEach(function(change) { + me.onPortalChanged(change.type, change.name, change.oldValue); + }); + }); + } else { // Firefox why no Object.observer ? :< + window.addHook('portalAdded', function(data) { + me.onPortalChanged('add', data.portal.options.guid, data.portal); + }); + // TODO: bug iitc dev for portalRemoved event + var oldDeletePortal = window.Render.prototype.deletePortalEntity; + window.Render.prototype.deletePortalEntity = function(guid) { + if (guid in window.portals) { + me.onPortalChanged('delete', guid, window.portals[guid]); + } + oldDeletePortal.apply(this, arguments); + }; + } + + this.missionStartLayer = new L.LayerGroup(); + this.missionLayer = new L.LayerGroup(); + + window.addLayerGroup('Mission start portals', this.missionStartLayer, false); + window.addLayerGroup('Mission portals', this.missionLayer, true); + + window.pluginCreateHook('missionLoaded'); + window.pluginCreateHook('portalMissionsLoaded'); + window.pluginCreateHook('missionFinished'); + window.pluginCreateHook('waypointFinished'); + } }; -var setup = window.plugin.missions.setup; +var setup = window.plugin.missions.setup.bind(window.plugin.missions); // PLUGIN END ////////////////////////////////////////////////////////// -@@PLUGINEND@@ +@@PLUGINEND@@ \ No newline at end of file From 3e7724afe607a692e7420c4dae9653bbbfefb8d1 Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Fri, 3 Apr 2015 20:50:10 +0100 Subject: [PATCH 03/45] first pass at changing map tile params for latest site update --- code/boot.js | 2 +- code/extract_niantic_parameters.js | 4 ++-- code/map_data_calc_tools.js | 16 +++++++--------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/code/boot.js b/code/boot.js index 50441c6b..fc997a63 100644 --- a/code/boot.js +++ b/code/boot.js @@ -165,7 +165,7 @@ window.setupMap = function() { center: [0,0], zoom: 1, zoomControl: (typeof android !== 'undefined' && android && android.showZoom) ? android.showZoom() : true, - minZoom: 5, + minZoom: MIN_ZOOM, // zoomAnimation: false, markerZoomAnimation: false, bounceAtZoomLimits: false diff --git a/code/extract_niantic_parameters.js b/code/extract_niantic_parameters.js index 9561db8a..c6421afe 100644 --- a/code/extract_niantic_parameters.js +++ b/code/extract_niantic_parameters.js @@ -76,7 +76,7 @@ window.extractFromStock = function() { // a reasonable array length for tile parameters // need to find two types: // a. portal level limits. decreasing numbers, starting at 8 - // b. tiles per edge. increasing numbers. current max is 9000 + // b. tiles per edge. increasing numbers. current max is 36000, 9000 was the previous value if (topObject[0] == 8) { // check for tile levels @@ -93,7 +93,7 @@ window.extractFromStock = function() { } } // end if (topObject[0] == 8) - if (topObject[topObject.length-1] == 9000) { + if (topObject[topObject.length-1] == 36000 || topObject[topObject.length-1] == 9000) { var increasing = true; for (var i=1; i topObject[i]) { diff --git a/code/map_data_calc_tools.js b/code/map_data_calc_tools.js index da273453..9e0b4d9d 100755 --- a/code/map_data_calc_tools.js +++ b/code/map_data_calc_tools.js @@ -10,14 +10,11 @@ // http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames + window.getMapZoomTileParameters = function(zoom) { -// var ZOOM_TO_TILES_PER_EDGE = [64, 64, 128, 128, 256, 256, 256, 1024, 1024, 1536, 4096, 4096, 6500, 6500, 6500]; -// var ZOOM_TO_TILES_PER_EDGE = [256, 256, 256, 256, 512, 512, 512, 2048, 2048, 2048, 4096, 4096, 6500, 6500, 6500]; - var ZOOM_TO_TILES_PER_EDGE = [256, 256, 256, 256, 512, 2048, 2048, 4096, 4096, 4096, 4096, 4096, 6500, 6500, 6500];; - var MAX_TILES_PER_EDGE = 9000; -// var ZOOM_TO_LEVEL = [8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1, 1]; - var ZOOM_TO_LEVEL = [8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 5, 4, 3, 2, 2, 1, 1]; + var ZOOM_TO_TILES_PER_EDGE = [256, 256, 256, 256, 512, 512, 512, 2048, 2048, 2048, 4096, 4096, 6500, 6500, 6500, 18e3, 18e3, 36e3]; + var ZOOM_TO_LEVEL = [ 8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1, 1 ]; if (niantic_params.ZOOM_TO_LEVEL && niantic_params.TILES_PER_EDGE) { ZOOM_TO_LEVEL = niantic_params.ZOOM_TO_LEVEL; @@ -35,13 +32,14 @@ window.getMapZoomTileParameters = function(zoom) { // reduce portal detail level by one - helps reduce clutter level = level+1; } - } + var maxTilesPerEdge = ZOOM_TO_TILES_PER_EDGE[ZOOM_TO_TILES_PER_EDGE.length-1]; + return { level: level, maxLevel: ZOOM_TO_LEVEL[zoom] || 0, // for reference, for log purposes, etc - tilesPerEdge: ZOOM_TO_TILES_PER_EDGE[zoom] || MAX_TILES_PER_EDGE, + tilesPerEdge: ZOOM_TO_TILES_PER_EDGE[zoom] || maxTilesPerEdge, zoom: zoom // include the zoom level, for reference }; } @@ -66,7 +64,7 @@ window.getDataZoomForMapZoom = function(zoom) { // to avoid impacting server load, we keep ourselves restricted to a zoom level with the sane numbre // of tilesPerEdge and portal levels visible - while (zoom > 5) { + while (zoom > MIN_ZOOM) { var newTileParams = getMapZoomTileParameters(zoom-1); if (newTileParams.tilesPerEdge != origTileParams.tilesPerEdge || newTileParams.level != origTileParams.level) { // switching to zoom-1 would result in a different detail level - so we abort changing things From e2cd19a9c307a326d23517db782f8be5f456a406 Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Fri, 3 Apr 2015 21:13:49 +0100 Subject: [PATCH 04/45] commit missing MIN_ZOOM --- main.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.js b/main.js index 6ffbe3cb..c0c9ef7f 100644 --- a/main.js +++ b/main.js @@ -160,7 +160,8 @@ window.MOD_TYPE = {RES_SHIELD:'Shield', MULTIHACK:'Multi-hack', FORCE_AMP:'Force window.ACCESS_INDICATOR_COLOR = 'orange'; window.RANGE_INDICATOR_COLOR = 'red' - +// min zoom for intel map - should match that used by stock intel +window.MIN_ZOOM = 3; window.DEFAULT_PORTAL_IMG = '//commondatastorage.googleapis.com/ingress.com/img/default-portal-image.png'; //window.NOMINATIM = '//nominatim.openstreetmap.org/search?format=json&limit=1&q='; From b4f9c3e2fe494a663399b1d110f432c42f6944e4 Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Fri, 3 Apr 2015 21:20:36 +0100 Subject: [PATCH 05/45] add some initialisation for deciding if to use detected tile params or those embedded in the code console warnings when it fails to detect values from stock, or the internal defaults don't match disable show-more-portals plugin if it would result in more requests - damn niantic! --- code/boot.js | 1 + code/map_data_calc_tools.js | 73 ++++++++++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/code/boot.js b/code/boot.js index fc997a63..4ebce81f 100644 --- a/code/boot.js +++ b/code/boot.js @@ -591,6 +591,7 @@ function boot() { window.setupTaphold(); window.setupStyles(); window.setupDialogs(); + window.setupDataTileParams(); window.setupMap(); window.setupOMS(); window.search.setup(); diff --git a/code/map_data_calc_tools.js b/code/map_data_calc_tools.js index 9e0b4d9d..f4d238ad 100755 --- a/code/map_data_calc_tools.js +++ b/code/map_data_calc_tools.js @@ -10,22 +10,69 @@ // http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames +window.setupDataTileParams = function() { + // default values - used to fall back to if we can't detect those used in stock intel + var DEFAULT_ZOOM_TO_TILES_PER_EDGE = [256, 256, 256, 256, 512, 512, 512, 2048, 2048, 2048, 4096, 4096, 6500, 6500, 6500, 18e3, 18e3, 36e3]; + var DEFAULT_ZOOM_TO_LEVEL = [ 8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1, 1 ]; + + + window.TILE_PARAMS = {}; + + if (niantic_params.ZOOM_TO_LEVEL && niantic_params.TILES_PER_EDGE) { + window.TILE_PARAMS.ZOOM_TO_LEVEL = niantic_params.ZOOM_TO_LEVEL; + window.TILE_PARAMS.TILES_PER_EDGE = niantic_params.TILES_PER_EDGE; + + + // lazy numerical array comparison + if ( JSON.stringify(niantic_params.ZOOM_TO_LEVEL) != JSON.stringify(DEFAULT_ZOOM_TO_LEVEL)) { + console.warn('Tile parameter ZOOM_TO_LEVEL have changed in stock intel. Detectec correct values, but code should be updated'); + debugger; + } + if ( JSON.stringify(niantic_params.TILES_PER_EDGE) != JSON.stringify(DEFAULT_ZOOM_TO_TILES_PER_EDGE)) { + console.warn('Tile parameter ZOOM_TO_LEVEL have changed in stock intel. Detectec correct values, but code should be updated'); + debugger; + } + + } else { + console.warn('Failed to detect both ZOOM_TO_LEVEL and TILES_PER_EDGE in the stock intel site - using internal defaults'); + debugger; + + window.TILE_PARAMS.ZOOM_TO_LEVEL = DEFAULT_ZOOM_TO_LEVEL; + window.TILE_PARAMS.TILES_PER_EDGE = DEFAULT_ZOOM_TO_TILES_PER_EDGE; + } + + // disable SHOW_MORE_PORTALS if it would be unfriendly to the servers (i.e. result in more requests) + // needs to be fired a bit later, after plugins have been initialised + setTimeout(function(){ + if (window.CONFIG_ZOOM_SHOW_MORE_PORTALS) { + if (window.TILE_PARAMS.TILES_PER_EDGE[17] > window.TILE_PARAMS.TILES_PER_EDGE[15]) { + var edgeScale = window.TILE_PARAMS.TILES_PER_EDGE[17]/window.TILE_PARAMS.TILES_PER_EDGE[15]; + var mapScale = edgeScale*edgeScale; + + dialog({ + title: 'Show more portals plugin disabled', + width: 400, + text: 'The "show-more-portals" plugin has been disabled.\n\n' + +'Niantic have changed the intel site so that zoom level 17 (all portals) now needs '+mapScale+' times more requests than level 15 (L1+ portals), so fetching at the wrong zoom level will be unfriendly to the servers\n\n' + }); + + window.CONFIG_ZOOM_SHOW_MORE_PORTALS=false; + } + } + }, 1); + +} + + window.getMapZoomTileParameters = function(zoom) { - var ZOOM_TO_TILES_PER_EDGE = [256, 256, 256, 256, 512, 512, 512, 2048, 2048, 2048, 4096, 4096, 6500, 6500, 6500, 18e3, 18e3, 36e3]; - var ZOOM_TO_LEVEL = [ 8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1, 1 ]; - if (niantic_params.ZOOM_TO_LEVEL && niantic_params.TILES_PER_EDGE) { - ZOOM_TO_LEVEL = niantic_params.ZOOM_TO_LEVEL; - ZOOM_TO_TILES_PER_EDGE = niantic_params.TILES_PER_EDGE; - } - - // the current API allows the client to request a minimum portal level. the ZOOM_TO_LEVEL list are minimums + // the current API allows the client to request a minimum portal level. the window.TILE_PARAMS.ZOOM_TO_LEVEL list are minimums // however, in my view, this can return excessive numbers of portals in many cases. let's try an optional reduction // of detail level at some zoom levels - var level = ZOOM_TO_LEVEL[zoom] || 0; // default to level 0 (all portals) if not in array + var level = window.TILE_PARAMS.ZOOM_TO_LEVEL[zoom] || 0; // default to level 0 (all portals) if not in array if (window.CONFIG_ZOOM_SHOW_LESS_PORTALS_ZOOMED_OUT) { if (level <= 7 && level >= 4) { @@ -34,12 +81,12 @@ window.getMapZoomTileParameters = function(zoom) { } } - var maxTilesPerEdge = ZOOM_TO_TILES_PER_EDGE[ZOOM_TO_TILES_PER_EDGE.length-1]; + var maxTilesPerEdge = window.TILE_PARAMS.TILES_PER_EDGE[window.TILE_PARAMS.TILES_PER_EDGE.length-1]; return { level: level, - maxLevel: ZOOM_TO_LEVEL[zoom] || 0, // for reference, for log purposes, etc - tilesPerEdge: ZOOM_TO_TILES_PER_EDGE[zoom] || maxTilesPerEdge, + maxLevel: window.TILE_PARAMS.ZOOM_TO_LEVEL[zoom] || 0, // for reference, for log purposes, etc + tilesPerEdge: window.TILE_PARAMS.TILES_PER_EDGE[zoom] || maxTilesPerEdge, zoom: zoom // include the zoom level, for reference }; } @@ -48,7 +95,7 @@ window.getMapZoomTileParameters = function(zoom) { window.getDataZoomForMapZoom = function(zoom) { // we can fetch data at a zoom level different to the map zoom. - //NOTE: the specifics of this are tightly coupled with the above ZOOM_TO_LEVEL and ZOOM_TO_TILES_PER_EDGE arrays + //NOTE: the specifics of this are tightly coupled with the above ZOOM_TO_LEVEL and TILES_PER_EDGE arrays // firstly, some of IITCs zoom levels, depending on base map layer, can be higher than stock. limit zoom level // (stock site max zoom may vary depending on google maps detail in the area - 20 or 21 max is common) From 2e906b41f0e1bcc5c75a3d8cc49173f4b27f0900 Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Fri, 3 Apr 2015 22:35:05 +0100 Subject: [PATCH 06/45] as well as 9000 and 36000, allow the interbediate 18000 when detecting map tile params this value was live for a short period of time, and they may revert back to it --- code/extract_niantic_parameters.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/extract_niantic_parameters.js b/code/extract_niantic_parameters.js index c6421afe..d55b1dc7 100644 --- a/code/extract_niantic_parameters.js +++ b/code/extract_niantic_parameters.js @@ -76,7 +76,7 @@ window.extractFromStock = function() { // a reasonable array length for tile parameters // need to find two types: // a. portal level limits. decreasing numbers, starting at 8 - // b. tiles per edge. increasing numbers. current max is 36000, 9000 was the previous value + // b. tiles per edge. increasing numbers. current max is 36000, 9000 was the previous value - 18000 is a likely possibility too if (topObject[0] == 8) { // check for tile levels @@ -93,7 +93,7 @@ window.extractFromStock = function() { } } // end if (topObject[0] == 8) - if (topObject[topObject.length-1] == 36000 || topObject[topObject.length-1] == 9000) { + if (topObject[topObject.length-1] == 36000 || topObject[topObject.length-1] == 18000 || topObject[topObject.length-1] == 9000) { var increasing = true; for (var i=1; i topObject[i]) { From 658344a832b8550d0564180923012844df9ed2f4 Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Sat, 4 Apr 2015 01:05:30 +0100 Subject: [PATCH 07/45] additional message asking users to direct their 'show more portals' issues towards niantic --- code/map_data_calc_tools.js | 1 + 1 file changed, 1 insertion(+) diff --git a/code/map_data_calc_tools.js b/code/map_data_calc_tools.js index f4d238ad..f1718e2b 100755 --- a/code/map_data_calc_tools.js +++ b/code/map_data_calc_tools.js @@ -54,6 +54,7 @@ window.setupDataTileParams = function() { width: 400, text: 'The "show-more-portals" plugin has been disabled.\n\n' +'Niantic have changed the intel site so that zoom level 17 (all portals) now needs '+mapScale+' times more requests than level 15 (L1+ portals), so fetching at the wrong zoom level will be unfriendly to the servers\n\n' + +'Don\'t like this? Ask Niantic to change the standard intel site, then IITC can match and all would benifit.' }); window.CONFIG_ZOOM_SHOW_MORE_PORTALS=false; From 0bdfd842179c9c6daab8efa1b3aedcfefcb86fc8 Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Sat, 4 Apr 2015 01:11:51 +0100 Subject: [PATCH 08/45] website: update for new release --- website/page/home.php | 7 +++++++ website/page/news.php | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/website/page/home.php b/website/page/home.php index d6af2d78..a96f02c2 100644 --- a/website/page/home.php +++ b/website/page/home.php @@ -11,6 +11,13 @@ offers many more features. It is available for mobile application.

+

Latest news

+ +

4th April 2015

+

+IITC 0.22.2 has been released. This is a critical update needed to fix portal loading at some zoom levels. +

+

20th March 2015

IITC 0.22.1 has been released. This is a critical update needed to fix COMM after a recent Niantic site update. diff --git a/website/page/news.php b/website/page/news.php index ed5c1167..41469ee1 100644 --- a/website/page/news.php +++ b/website/page/news.php @@ -1,5 +1,10 @@

News

+

4th April 2015

+

+IITC 0.22.2 has been released. This is a critical update needed to fix portal loading at some zoom levels. +

+

20th March 2015

IITC 0.22.1 has been released. This is a critical update needed to fix COMM after a recent Niantic site update. From 1fcf7c51a18f51e5bf1750b9c5353b9f84a7e14b Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Sat, 4 Apr 2015 01:14:26 +0100 Subject: [PATCH 09/45] bump version after release --- main.js | 2 +- mobile/AndroidManifest.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/main.js b/main.js index c0c9ef7f..6b3abc75 100644 --- a/main.js +++ b/main.js @@ -1,7 +1,7 @@ // ==UserScript== // @id ingress-intel-total-conversion@jonatkins // @name IITC: Ingress intel map total conversion -// @version 0.22.2.@@DATETIMEVERSION@@ +// @version 0.22.3.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ diff --git a/mobile/AndroidManifest.xml b/mobile/AndroidManifest.xml index 5a7efee2..b321e098 100644 --- a/mobile/AndroidManifest.xml +++ b/mobile/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="96" + android:versionName="0.22.3"> Date: Tue, 7 Apr 2015 21:55:17 +0100 Subject: [PATCH 10/45] minor tweaks to wording - less verbose --- plugins/missions.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/missions.user.js b/plugins/missions.user.js index aa76a29a..86d68e75 100644 --- a/plugins/missions.user.js +++ b/plugins/missions.user.js @@ -89,7 +89,7 @@ window.plugin.missions = { // After select. setTimeout(function() { // #resodetails - $('.linkdetails').append('Open mission(s)'); + $('.linkdetails').append('Missions'); }, 0); }, @@ -622,7 +622,7 @@ window.plugin.missions = { this.settings.checkedMissions = {}; } - $('#toolbox').append('Open mission(s) in window'); + $('#toolbox').append('Missions in view'); // window.addPortalHighlighter('Mission start point', this.highlight.bind(this)); window.addHook('portalSelected', this.onPortalSelected.bind(this)); @@ -668,4 +668,4 @@ var setup = window.plugin.missions.setup.bind(window.plugin.missions); // PLUGIN END ////////////////////////////////////////////////////////// -@@PLUGINEND@@ \ No newline at end of file +@@PLUGINEND@@ From c7595c85f8de8c5baa212d2d2f1488ce69eb17f5 Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Tue, 7 Apr 2015 21:59:05 +0100 Subject: [PATCH 11/45] add missing