forked from iitc-project/ingress-intel-total-conversion
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.js
277 lines (241 loc) · 11.6 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
// ==UserScript==
// @id ingress-intel-total-conversion@jonatkins
// @name IITC: Ingress intel map total conversion
// @version 0.13.4.@@DATETIMEVERSION@@
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL @@UPDATEURL@@
// @downloadURL @@DOWNLOADURL@@
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Total conversion for the ingress intel map.
// @include http://www.ingress.com/intel*
// @include https://www.ingress.com/intel*
// @match http://www.ingress.com/intel*
// @match https://www.ingress.com/intel*
// @grant none
// ==/UserScript==
// REPLACE ORIG SITE ///////////////////////////////////////////////////
if(document.getElementsByTagName('html')[0].getAttribute('itemscope') != null)
throw('Ingress Intel Website is down, not a userscript issue.');
window.iitcBuildDate = '@@BUILDDATE@@';
// disable vanilla JS
window.onload = function() {};
document.body.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();', 3*1000);
throw('Page doesn’t have player data, but you are logged in. Reloading in 3s.');
}
// 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": "ENLIGHTENED||RESISTANCE"};
// 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 = ''
+ '<title>Ingress Intel Map</title>'
+ '<style>@@INCLUDESTRING:style.css@@</style>'
+ '<style>@@INCLUDESTRING:external/leaflet.css@@</style>'
//note: smartphone.css injection moved into code/smartphone.js
+ '<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Coda"/>'
+ '<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Roboto"/>';
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"><table><tr>'
+ ' <td><time></time></td>'
+ ' <td><mark>tell faction:</mark></td>'
+ ' <td><input id="chattext" type="text" maxlength="256" /></td>'
+ '</tr></table></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>'
+ ' <div id="geosearchwrapper">'
+ ' <input id="geosearch" placeholder="Search location…" type="text"/>'
+ ' <img src="@@INCLUDEIMAGE:images/current-location.png@@"/ title="Current Location">'
+ ' </div>'
+ ' <div id="portaldetails"></div>'
// redeeming removed from stock site, so commented out for now. it may return...
// + ' <input id="redeem" placeholder="Redeem code…" type="text"/>'
+ ' <div id="toolbox">'
+ ' <a onmouseover="setPermaLink(this)" onclick="setPermaLink(this);return androidPermalink()" title="URL link to this map view">Permalink</a>'
+ ' <a onclick="window.aboutIITC()" style="cursor: help">About IITC</a>'
+ ' </div>'
+ ' </div>'
+ '</div>'
+ '<div id="updatestatus"><div id="innerstatus"></div></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 = 60; // refresh view every 30s (base time)
window.ZOOM_LEVEL_ADJ = 5; // add 5 seconds per zoom level
window.ON_MOVE_REFRESH = 2.5; //refresh time to use after a movement event
window.MINIMUM_OVERRIDE_REFRESH = 10; //limit on refresh time since previous refresh, limiting repeated move refresh rate
window.REFRESH_GAME_SCORE = 15*60; // refresh game score every 15 minutes
window.MAX_IDLE_TIME = 4*60; // 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 = 100;
// 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;
// Minimum area to zoom ratio that field MU's will display
window.FIELD_MU_DISPLAY_AREA_ZOOM_RATIO = 0.001;
// Point tolerance for displaying MU's
window.FIELD_MU_DISPLAY_POINT_TOLERANCE = 60
window.COLOR_SELECTED_PORTAL = '#f00';
window.COLORS = ['#FF9900', '#0088FF', '#03DC03']; // 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'};
window.OPTIONS_RESONATOR_SELECTED = {color: '#fff', weight: 2, radius: 4, opacity: 1, clickable: false};
window.OPTIONS_RESONATOR_NON_SELECTED = {color: '#aaa', weight: 1, radius: 3, opacity: 1, clickable: false};
window.MOD_TYPE = {RES_SHIELD:'Shield', MULTIHACK:'Multi-hack', FORCE_AMP:'Force Amp', HEATSINK:'Heat Sink', TURRET:'Turret', LINK_AMPLIFIER: 'Link Amp'};
window.OPTIONS_RESONATOR_LINE_SELECTED = {
opacity: 0.7,
weight: 3,
color: '#FFA000',
dashArray: '0,10' + (new Array(25).join(',8,4')),
fill: false,
clickable: false
};
window.OPTIONS_RESONATOR_LINE_NON_SELECTED = {
opacity: 0.25,
weight: 2,
color: '#FFA000',
dashArray: '0,10' + (new Array(25).join(',8,4')),
fill: false,
clickable: false
};
// 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'
// by how much pixels should the portal range be expanded on mobile
// devices. This should make clicking them easier.
window.PORTAL_RADIUS_ENLARGE_MOBILE = 5;
window.DEFAULT_PORTAL_IMG = '//commondatastorage.googleapis.com/ingress.com/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/
window.RESO_NRG = [0, 1000, 1500, 2000, 2500, 3000, 4000, 5000, 6000];
window.MAX_XM_PER_LEVEL = [0, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000];
window.MIN_AP_FOR_LEVEL = [0, 10000, 30000, 70000, 150000, 300000, 600000, 1200000];
window.HACK_RANGE = 40; // in meters, max. distance from portal to be able to access it
window.OCTANTS = ['E', 'NE', 'N', 'NW', 'W', 'SW', 'S', 'SE'];
window.OCTANTS_ARROW = ['→', '↗', '↑', '↖', '←', '↙', '↓', '↘'];
window.DESTROY_RESONATOR = 75; //AP for destroying portal
window.DESTROY_LINK = 187; //AP for destroying link
window.DESTROY_FIELD = 750; //AP for destroying field
window.CAPTURE_PORTAL = 500; //AP for capturing a portal
window.DEPLOY_RESONATOR = 125; //AP for deploying a resonator
window.COMPLETION_BONUS = 250; //AP for deploying all resonators on portal
window.UPGRADE_ANOTHERS_RESONATOR = 65; //AP for upgrading another's resonator
window.MAX_PORTAL_LEVEL = 8;
window.MAX_RESO_PER_PLAYER = [0, 8, 4, 4, 4, 2, 2, 1, 1];
// OTHER MORE-OR-LESS CONSTANTS //////////////////////////////////////
window.TEAM_NONE = 0;
window.TEAM_RES = 1;
window.TEAM_ENL = 2;
window.TEAM_TO_CSS = ['none', 'res', 'enl'];
window.TYPE_UNKNOWN = 0;
window.TYPE_PORTAL = 1;
window.TYPE_LINK = 2;
window.TYPE_FIELD = 3;
window.TYPE_PLAYER = 4;
window.TYPE_CHAT = 5;
window.TYPE_RESONATOR = 6;
window.SLOT_TO_LAT = [0, Math.sqrt(2)/2, 1, Math.sqrt(2)/2, 0, -Math.sqrt(2)/2, -1, -Math.sqrt(2)/2];
window.SLOT_TO_LNG = [1, Math.sqrt(2)/2, 0, -Math.sqrt(2)/2, -1, -Math.sqrt(2)/2, 0, Math.sqrt(2)/2];
window.EARTH_RADIUS=6378137;
window.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.portalsCount = 0;
window.links = {};
window.linksCount = 0;
window.fields = {};
window.fieldsCount = 0;
window.resonators = {};
// contain current status(on/off) of overlay layerGroups.
// But you should use isLayerGroupDisplayed(name) to check the status
window.overlayStatus = {};
// plugin framework. Plugins may load earlier than iitc, so don’t
// overwrite data
if(typeof window.plugin !== 'function') window.plugin = function() {};
@@INJECTCODE@@
} // 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);