220 lines
9.7 KiB
JavaScript
220 lines
9.7 KiB
JavaScript
// ==UserScript==
|
||
// @id ingress-intel-total-conversion@breunigs
|
||
// @name intel map total conversion
|
||
// @version 0.6-@@BUILDDATE@@
|
||
// @namespace https://github.com/breunigs/ingress-intel-total-conversion
|
||
// @updateURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/dist/total-conversion-build.user.js
|
||
// @downloadURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/dist/total-conversion-build.user.js
|
||
// @description total conversion for the ingress intel map.
|
||
// @include http://www.ingress.com/intel*
|
||
// @match http://www.ingress.com/intel*
|
||
// ==/UserScript==
|
||
|
||
|
||
// REPLACE ORIG SITE ///////////////////////////////////////////////////
|
||
if(document.getElementsByTagName('html')[0].getAttribute('itemscope') != null)
|
||
throw('Ingress Intel Website is down, not a userscript issue.');
|
||
|
||
// disable vanilla JS
|
||
window.onload = function() {};
|
||
|
||
// rescue user data from original page
|
||
var scr = document.getElementsByTagName('script');
|
||
for(var x in scr) {
|
||
var s = scr[x];
|
||
if(s.src) continue;
|
||
if(s.type !== 'text/javascript') continue;
|
||
var d = s.innerHTML.split('\n');
|
||
break;
|
||
}
|
||
|
||
|
||
if(!d) {
|
||
// page doesn’t have a script tag with player information.
|
||
if(document.getElementById('header_email')) {
|
||
// however, we are logged in.
|
||
setTimeout('location.reload();', 10*1000);
|
||
throw('Page doesn’t have player data, but you are logged in. Reloading in 10s.');
|
||
}
|
||
// FIXME: handle nia takedown in progress
|
||
throw('Couldn’t retrieve player data. Are you logged in?');
|
||
}
|
||
|
||
|
||
for(var i = 0; i < d.length; i++) {
|
||
if(!d[i].match('var PLAYER = ')) continue;
|
||
eval(d[i].match(/^var /, 'window.'));
|
||
break;
|
||
}
|
||
// player information is now available in a hash like this:
|
||
// window.PLAYER = {"ap": "123", "energy": 123, "available_invites": 123, "nickname": "somenick", "team": "ALIENS||RESISTANCE"};
|
||
|
||
var ir = window.internalResources || [];
|
||
|
||
// remove complete page. We only wanted the user-data and the page’s
|
||
// security context so we can access the API easily. Setup as much as
|
||
// possible without requiring scripts.
|
||
document.getElementsByTagName('head')[0].innerHTML = ''
|
||
//~ + '<link rel="stylesheet" type="text/css" href="http://0.0.0.0:8000/style.css"/>'
|
||
+ '<title>Ingress Intel Map</title>'
|
||
+ (ir.indexOf('mainstyle') === -1
|
||
? '<link rel="stylesheet" type="text/css" href="http://breunigs.github.com/ingress-intel-total-conversion/style.css?@@BUILDDATE@@"/>'
|
||
: '')
|
||
+ (ir.indexOf('leafletcss') === -1
|
||
? '<link rel="stylesheet" type="text/css" href="http://cdn.leafletjs.com/leaflet-0.5/leaflet.css"/>'
|
||
: '')
|
||
+ (ir.indexOf('codafont') === -1
|
||
? '<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Coda"/>'
|
||
: '');
|
||
|
||
document.getElementsByTagName('body')[0].innerHTML = ''
|
||
+ '<div id="map">Loading, please wait</div>'
|
||
+ '<div id="chatcontrols" style="display:none">'
|
||
+ ' <a><span class="toggle expand"></span></a>'
|
||
+ '<a>full</a><a>compact</a><a>public</a><a class="active">faction</a>'
|
||
+ '</div>'
|
||
+ '<div id="chat" style="display:none">'
|
||
+ ' <div id="chatfaction"></div>'
|
||
+ ' <div id="chatpublic"></div>'
|
||
+ ' <div id="chatcompact"></div>'
|
||
+ ' <div id="chatfull"></div>'
|
||
+ '</div>'
|
||
+ '<form id="chatinput" style="display:none"><time></time><span>tell faction:</span><input type="text"/></form>'
|
||
+ '<a id="sidebartoggle"><span class="toggle close"></span></a>'
|
||
+ '<div id="scrollwrapper">' // enable scrolling for small screens
|
||
+ ' <div id="sidebar" style="display: none">'
|
||
+ ' <div id="playerstat">t</div>'
|
||
+ ' <div id="gamestat"> loading global control stats</div>'
|
||
+ ' <input id="geosearch" placeholder="Search location…" type="text"/>'
|
||
+ ' <div id="portaldetails"></div>'
|
||
+ ' <input id="redeem" placeholder="Redeem code…" type="text"/>'
|
||
+ ' <div id="toolbox">'
|
||
+ ' <a onmouseover="setPermaLink(this)">permalink</a>'
|
||
+ ' <a href="https://github.com/breunigs/ingress-intel-total-conversion#readme" title="IITC = Ingress Intel Total Conversion.\n\nOn the script’s homepage you can:\n– find updates\n– get plugins\n– report bugs\n– and contribute." style="cursor: help">IITC’s page</a></div>'
|
||
+ ' </div>'
|
||
+ '</div>'
|
||
+ '<div id="updatestatus"></div>';
|
||
|
||
// putting everything in a wrapper function that in turn is placed in a
|
||
// script tag on the website allows us to execute in the site’s context
|
||
// instead of in the Greasemonkey/Extension/etc. context.
|
||
function wrapper() {
|
||
|
||
// LEAFLET PREFER CANVAS ///////////////////////////////////////////////
|
||
// Set to true if Leaflet should draw things using Canvas instead of SVG
|
||
// Disabled for now because it has several bugs: flickering, constant
|
||
// CPU usage and it continuously fires the moveend event.
|
||
L_PREFER_CANVAS = false;
|
||
|
||
// CONFIG OPTIONS ////////////////////////////////////////////////////
|
||
window.REFRESH = 30; // refresh view every 30s (base time)
|
||
window.ZOOM_LEVEL_ADJ = 5; // add 5 seconds per zoom level
|
||
window.REFRESH_GAME_SCORE = 5*60; // refresh game score every 5 minutes
|
||
window.MAX_IDLE_TIME = 4; // stop updating map after 4min idling
|
||
window.PRECACHE_PLAYER_NAMES_ZOOM = 17; // zoom level to start pre-resolving player names
|
||
window.HIDDEN_SCROLLBAR_ASSUMED_WIDTH = 20;
|
||
window.SIDEBAR_WIDTH = 300;
|
||
// chat messages are requested for the visible viewport. On high zoom
|
||
// levels this gets pretty pointless, so request messages in at least a
|
||
// X km radius.
|
||
window.CHAT_MIN_RANGE = 6;
|
||
// this controls how far data is being drawn outside the viewport. Set
|
||
// it 0 to only draw entities that intersect the current view. A value
|
||
// of one will render an area twice the size of the viewport (or some-
|
||
// thing like that, Leaflet doc isn’t too specific). Setting it too low
|
||
// makes the missing data on move/zoom out more obvious. Setting it too
|
||
// high causes too many items to be drawn, making drag&drop sluggish.
|
||
window.VIEWPORT_PAD_RATIO = 0.3;
|
||
|
||
// how many items to request each query
|
||
window.CHAT_PUBLIC_ITEMS = 200;
|
||
window.CHAT_FACTION_ITEMS = 50;
|
||
// how many pixels to the top before requesting new data
|
||
window.CHAT_REQUEST_SCROLL_TOP = 200;
|
||
window.CHAT_SHRINKED = 60;
|
||
|
||
// Leaflet will get very slow for MANY items. It’s better to display
|
||
// only some instead of crashing the browser.
|
||
window.MAX_DRAWN_PORTALS = 1000;
|
||
window.MAX_DRAWN_LINKS = 400;
|
||
window.MAX_DRAWN_FIELDS = 200;
|
||
// Minimum zoom level resonator will display
|
||
window.RESONATOR_DISPLAY_ZOOM_LEVEL = 17;
|
||
|
||
window.COLOR_SELECTED_PORTAL = '#f00';
|
||
window.COLORS = ['#FFCE00', '#0088FF', '#03FE03']; // none, res, enl
|
||
window.COLORS_LVL = ['#000', '#FECE5A', '#FFA630', '#FF7315', '#E40000', '#FD2992', '#EB26CD', '#C124E0', '#9627F4'];
|
||
window.COLORS_MOD = {VERY_RARE: '#F78AF6', RARE: '#AD8AFF', COMMON: '#84FBBD'};
|
||
|
||
|
||
// circles around a selected portal that show from where you can hack
|
||
// it and how far the portal reaches (i.e. how far links may be made
|
||
// from this portal)
|
||
window.ACCESS_INDICATOR_COLOR = 'orange';
|
||
window.RANGE_INDICATOR_COLOR = 'red';
|
||
|
||
|
||
window.DEFAULT_PORTAL_IMG = 'http://commondatastorage.googleapis.com/ingress/img/default-portal-image.png';
|
||
window.NOMINATIM = 'http://nominatim.openstreetmap.org/search?format=json&limit=1&q=';
|
||
|
||
// INGRESS CONSTANTS /////////////////////////////////////////////////
|
||
// http://decodeingress.me/2012/11/18/ingress-portal-levels-and-link-range/
|
||
var RESO_NRG = [0, 1000, 1500, 2000, 2500, 3000, 4000, 5000, 6000];
|
||
var MAX_XM_PER_LEVEL = [0, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000];
|
||
var MIN_AP_FOR_LEVEL = [0, 10000, 30000, 70000, 150000, 300000, 600000, 1200000];
|
||
var HACK_RANGE = 40; // in meters, max. distance from portal to be able to access it
|
||
var OCTANTS = ['E', 'NE', 'N', 'NW', 'W', 'SW', 'S', 'SE'];
|
||
var DESTROY_RESONATOR = 75; //AP for destroying portal
|
||
var DESTROY_LINK = 187; //AP for destroying link
|
||
var DESTROY_FIELD = 750; //AP for destroying field
|
||
var CAPTURE_PORTAL = 500; //AP for capturing a portal
|
||
var DEPLOY_RESONATOR = 125; //AP for deploying a resonator
|
||
var COMPLETION_BONUS = 250; //AP for deploying all resonators on portal
|
||
|
||
// OTHER MORE-OR-LESS CONSTANTS //////////////////////////////////////
|
||
var TEAM_NONE = 0, TEAM_RES = 1, TEAM_ENL = 2;
|
||
var TEAM_TO_CSS = ['none', 'res', 'enl'];
|
||
var TYPE_UNKNOWN = 0, TYPE_PORTAL = 1, TYPE_LINK = 2, TYPE_FIELD = 3, TYPE_PLAYER = 4, TYPE_CHAT = 5, TYPE_RESONATOR = 6;
|
||
|
||
var SLOT_TO_LAT = [0, Math.sqrt(2)/2, 1, Math.sqrt(2)/2, 0, -Math.sqrt(2)/2, -1, -Math.sqrt(2)/2];
|
||
var SLOT_TO_LNG = [1, Math.sqrt(2)/2, 0, -Math.sqrt(2)/2, -1, -Math.sqrt(2)/2, 0, Math.sqrt(2)/2];
|
||
var EARTH_RADIUS=6378137;
|
||
var DEG2RAD = Math.PI / 180;
|
||
|
||
// STORAGE ///////////////////////////////////////////////////////////
|
||
// global variables used for storage. Most likely READ ONLY. Proper
|
||
// way would be to encapsulate them in an anonymous function and write
|
||
// getters/setters, but if you are careful enough, this works.
|
||
var refreshTimeout;
|
||
var urlPortal = null;
|
||
window.playersToResolve = [];
|
||
window.playersInResolving = [];
|
||
window.selectedPortal = null;
|
||
window.portalRangeIndicator = null;
|
||
window.portalAccessIndicator = null;
|
||
window.mapRunsUserAction = false;
|
||
var portalsLayers, linksLayer, fieldsLayer;
|
||
|
||
// contain references to all entities shown on the map. These are
|
||
// automatically kept in sync with the items on *sLayer, so never ever
|
||
// write to them.
|
||
window.portals = {};
|
||
window.links = {};
|
||
window.fields = {};
|
||
window.resonators = {};
|
||
|
||
// plugin framework. Plugins may load earlier than iitc, so don’t
|
||
// overwrite data
|
||
if(typeof window.plugin !== 'function') window.plugin = function() {};
|
||
|
||
|
||
@@INJECTHERE@@
|
||
|
||
|
||
} // end of wrapper
|
||
|
||
// inject code into site context
|
||
var script = document.createElement('script');
|
||
script.appendChild(document.createTextNode('('+ wrapper +')();'));
|
||
(document.body || document.head || document.documentElement).appendChild(script);
|