diff --git a/code/boot.js b/code/boot.js
index 1d12689b..f3ffd98e 100644
--- a/code/boot.js
+++ b/code/boot.js
@@ -1,5 +1,4 @@
-
// SETUP /////////////////////////////////////////////////////////////
// these functions set up specific areas after the boot function
// created a basic framework. All of these functions should only ever
@@ -104,10 +103,10 @@ window.setupStyles = function() {
window.setupMap = function() {
$('#map').text('');
- var osmOpt = {attribution: 'Map data © OpenStreetMap contributors', maxZoom: 18};
+ var osmOpt = {attribution: 'Map data © OpenStreetMap contributors', maxZoom: 18, detectRetina: true};
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', osmOpt);
- var cmOpt = {attribution: 'Map data © OpenStreetMap contributors, Imagery © CloudMade', maxZoom: 18};
+ var cmOpt = {attribution: 'Map data © OpenStreetMap contributors, Imagery © CloudMade', maxZoom: 18, detectRetina: true};
var cmMin = new L.TileLayer('http://{s}.tile.cloudmade.com/654cef5fd49a432ab81267e200ecc502/22677/256/{z}/{x}/{y}.png', cmOpt);
var cmMid = new L.TileLayer('http://{s}.tile.cloudmade.com/654cef5fd49a432ab81267e200ecc502/999/256/{z}/{x}/{y}.png', cmOpt);
diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java b/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java
index ea8d65b2..7a1c1db9 100644
--- a/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java
+++ b/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java
@@ -1,5 +1,7 @@
package com.cradle.iitc_mobile;
+import java.io.IOException;
+
import com.cradle.iitc_mobile.R;
import android.net.Uri;
@@ -111,6 +113,11 @@ public class IITC_Mobile extends Activity {
switch (item.getItemId()) {
case R.id.reload_button:
iitc_view.reload();
+ try {
+ iitc_view.getWebViewClient().loadIITC_JS(this);
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ }
return true;
// print version number
case R.id.version_num:
diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java b/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java
index 9440df04..745060fa 100644
--- a/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java
+++ b/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java
@@ -55,4 +55,8 @@ public class IITC_WebView extends WebView {
}
//----------------------------------------------------------------
+ public IITC_WebViewClient getWebViewClient() {
+ return this.webclient;
+ }
+
}
diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_WebViewClient.java b/mobile/src/com/cradle/iitc_mobile/IITC_WebViewClient.java
index 8da836d6..0ef26879 100644
--- a/mobile/src/com/cradle/iitc_mobile/IITC_WebViewClient.java
+++ b/mobile/src/com/cradle/iitc_mobile/IITC_WebViewClient.java
@@ -16,7 +16,7 @@ public class IITC_WebViewClient extends WebViewClient {
"body, #dashboard_container, #map_canvas { background: #000 !important; }".getBytes());
private static final ByteArrayInputStream empty = new ByteArrayInputStream("".getBytes());
- private static WebResourceResponse iitcjs;
+ private WebResourceResponse iitcjs;
public IITC_WebViewClient(Context c) {
try {
@@ -26,7 +26,7 @@ public class IITC_WebViewClient extends WebViewClient {
}
}
- private static void loadIITC_JS(Context c) throws java.io.IOException {
+ public void loadIITC_JS(Context c) throws java.io.IOException {
InputStream input;
input = c.getAssets().open("iitc.js");
@@ -59,7 +59,6 @@ public class IITC_WebViewClient extends WebViewClient {
// with our own content. This is used to block loading Niantic resources
// which aren’t required and to inject IITC early into the site.
// via http://stackoverflow.com/a/8274881/1684530
- @SuppressWarnings("static-access")
@Override
public WebResourceResponse shouldInterceptRequest (final WebView view, String url) {
if(url.contains("/css/common.css")) {
diff --git a/plugins/scoreboard.user.js b/plugins/scoreboard.user.js
new file mode 100644
index 00000000..f7ddffa4
--- /dev/null
+++ b/plugins/scoreboard.user.js
@@ -0,0 +1,324 @@
+// ==UserScript==
+// @id iitc-plugin-scoreboard@vita10gy
+// @name iitc: show a localized scoreboard.
+// @version 0.1.1
+// @namespace https://github.com/breunigs/ingress-intel-total-conversion
+// @updateURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/scoreboard.user.js
+// @downloadURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/scoreboard.user.js
+// @description A localized scoreboard.
+// @include https://www.ingress.com/intel*
+// @match https://www.ingress.com/intel*
+// ==/UserScript==
+
+function wrapper() {
+// ensure plugin framework is there, even if iitc is not yet loaded
+if(typeof window.plugin !== 'function') window.plugin = function() {};
+
+
+// PLUGIN START ////////////////////////////////////////////////////////
+
+// use own namespace for plugin
+window.plugin.scoreboard = function() {};
+
+window.plugin.scoreboard.scores = {};
+window.plugin.scoreboard.playerGuids = new Array();
+
+window.plugin.scoreboard.resetTeam = function(team) {
+ var scores = window.plugin.scoreboard.scores['team'];
+ scores[team] = {};
+ scores[team]['mu'] = 0;
+ scores[team]['count_fields'] = 0;
+ scores[team]['count_links'] = 0;
+ scores[team]['count_portals'] = 0;
+ scores[team]['count_resonators'] = 0;
+ scores[team]['largest'] = {};
+};
+
+window.plugin.scoreboard.initPlayer = function(player, team) {
+ var scores = window.plugin.scoreboard.scores['player'];
+ if(scores[player] === undefined) {
+ scores[player] = {};
+ scores[player]['team'] = team;
+ scores[player]['mu'] = 0;
+ scores[player]['count_fields'] = 0;
+ scores[player]['count_links'] = 0;
+ scores[player]['count_portals'] = 0;
+ scores[player]['count_resonators'] = 0;
+ // scores[player]['count_shields'] = 0;
+ scores[player]['largest'] = {};
+ window.plugin.scoreboard.playerGuids.push(player);
+ }
+}
+
+window.plugin.scoreboard.compileStats = function() {
+ var somethingInView = false;
+ window.plugin.scoreboard.playerGuids = new Array();
+ window.plugin.scoreboard.scores = {'team': {}, 'player': {}};
+ var scores = window.plugin.scoreboard.scores;
+ window.plugin.scoreboard.resetTeam(TEAM_RES);
+ window.plugin.scoreboard.resetTeam(TEAM_ENL);
+
+ $.each(window.fields, function(qk, val) {
+ var team = getTeam(val.options.data);
+ var player = val.options.data.creator.creatorGuid;
+
+ window.plugin.scoreboard.initPlayer(player,team);
+
+ // Google sends fields long since dead in the data. This makes sure it's still actually up.
+ if(window.portals[val.options.vertices.vertexA.guid] !== undefined ||
+ window.portals[val.options.vertices.vertexB.guid] !== undefined ||
+ window.portals[val.options.vertices.vertexC.guid] !== undefined ) {
+
+ somethingInView = true;
+ scores['team'][team]['mu'] += parseInt(val.options.data.entityScore.entityScore);
+ scores['player'][player]['mu'] += parseInt(val.options.data.entityScore.entityScore);
+ scores['team'][team]['count_fields']++;
+ scores['player'][player]['count_fields']++;
+
+ var largestMu = scores['team'][team]['largest']['mu'];
+ if(largestMu === undefined || parseInt(largestMu.options.data.entityScore.entityScore) < parseInt(val.options.data.entityScore.entityScore)) {
+ largestMu = val;
+ }
+ scores['team'][team]['largest']['mu'] = largestMu;
+
+ var largestMu = scores['player'][player]['largest']['mu'];
+ if(largestMu === undefined || parseInt(largestMu.options.data.entityScore.entityScore) < parseInt(val.options.data.entityScore.entityScore)) {
+ largestMu = val;
+ }
+ scores['player'][player]['largest']['mu'] = largestMu;
+ }
+ });
+ $.each(window.links, function(qk, link) {
+ somethingInView = true;
+ var team = getTeam(link.options.data);
+ var player = link.options.data.creator.creatorGuid;
+ window.plugin.scoreboard.initPlayer(player, team);
+ scores['team'][team]['count_links']++;
+ scores['player'][player]['count_links']++;
+ });
+ $.each(window.portals, function(qk, portal) {
+ somethingInView = true;
+ var team = getTeam(portal.options.details);
+ var player = portal.options.details.captured.capturingPlayerId;
+ window.plugin.scoreboard.initPlayer(player, team);
+ scores['team'][team]['count_portals']++;
+ scores['player'][player]['count_portals']++;
+
+ //$.each(portal.options.details.portalV2.linkedModArray, function(ind, mod) {
+ // if(mod !== null) {
+ // somethingInView = true;
+ // scores['team'][team]['count_shields']++;
+ // scores['player'][mod.installingUser]['count_shields']++;
+ // }
+ //});
+
+ $.each(portal.options.details.resonatorArray.resonators, function(ind, reso) {
+ if(reso !== null) {
+ somethingInView = true;
+ window.plugin.scoreboard.initPlayer(reso.ownerGuid, team);
+ scores['team'][team]['count_resonators']++;
+ scores['player'][reso.ownerGuid]['count_resonators']++;
+ }
+ });
+ });
+ return somethingInView;
+};
+
+window.plugin.scoreboard.percentSpan = function(percent, cssClass) {
+ var retVal = '';
+ if(percent > 0) {
+ retVal += '' + percent;
+ if(percent >= 7) { // anything less than this and the text doesnt fit in the span.
+ retVal += '%';
+ }
+ retVal += '';
+ }
+ return retVal;
+};
+
+window.plugin.scoreboard.teamTableRow = function(field,title) {
+ var scores = window.plugin.scoreboard.scores['team'];
+ var retVal = '
'
+ + title
+ + ' | '
+ + window.digits(scores[TEAM_RES][field])
+ + ' | '
+ + window.digits(scores[TEAM_ENL][field])
+ + ' | '
+ + window.digits(scores[TEAM_RES][field] + scores[TEAM_ENL][field])
+ + ' |
';
+ return retVal;
+};
+
+window.plugin.scoreboard.fieldInfo = function(field) {
+ var title = '';
+ var retVal = '';
+
+ if(field !== undefined) {
+ var portal = window.portals[field.options.vertices.vertexA.guid];
+ if(portal !== undefined) {
+ title = ' @' + portal.options.details.portalV2.descriptiveText.TITLE;
+ }
+
+ retVal = ''
+ + field.options.data.entityScore.entityScore
+ + ' - ' + window.getPlayerName(field.options.data.creator.creatorGuid)
+ + '
';
+ } else {
+ retVal = 'N/A';
+ }
+ return retVal;
+};
+
+window.plugin.scoreboard.playerTableRow = function(playerGuid) {
+ var scores = window.plugin.scoreboard.scores['player'];
+ var retVal = ''
+ + window.getPlayerName(playerGuid);
+ + ' | ';
+
+ $.each(['mu','count_fields','count_links','count_portals','count_resonators'], function(i, field) {
+ retVal += ''
+ + window.digits(scores[playerGuid][field])
+ + ' | ';
+ });
+ retVal += '
';
+ return retVal;
+};
+
+window.plugin.scoreboard.playerTable = function(sortBy) {
+
+ // Sort the playerGuid array by sortBy
+ window.plugin.scoreboard.playerGuids.sort(function(a, b) {
+ var playerA = window.plugin.scoreboard.scores['player'][a];
+ var playerB = window.plugin.scoreboard.scores['player'][b];
+ var retVal = 0;
+ if(sortBy === 'names') {
+ retVal = window.getPlayerName(a).toLowerCase() < window.getPlayerName(b).toLowerCase() ? -1 : 1;
+ } else {
+ retVal = playerB[sortBy] - playerA[sortBy];
+ }
+ return retVal;
+ });
+
+ var sort = window.plugin.scoreboard.playerTableSort;
+ var scoreHtml = ''
+ + 'Player | '
+ + 'Mu | '
+ + 'Fields | '
+ + 'Links | '
+ + 'Portals | '
+ + 'Resonators |
';
+ $.each(window.plugin.scoreboard.playerGuids, function(index, guid) {
+ scoreHtml += window.plugin.scoreboard.playerTableRow(guid);
+ });
+ scoreHtml += '
';
+
+ return scoreHtml;
+}
+
+// A little helper functon so the above isn't so messy
+window.plugin.scoreboard.playerTableSort = function(name, by) {
+ var retVal = 'data-sort="' + name + '"';
+ if(name === by) {
+ retVal += ' class="sorted"';
+ }
+ return retVal;
+};
+
+window.plugin.scoreboard.display = function() {
+
+ var somethingInView = window.plugin.scoreboard.compileStats();
+ var scores = window.plugin.scoreboard.scores;
+ var resMu = scores['team'][TEAM_RES]['mu'];
+ var enlMu = scores['team'][TEAM_ENL]['mu'];
+ var scoreHtml = '';
+
+ if(somethingInView) {
+
+ if(resMu + enlMu > 0) {
+ var resMuPercent = Math.round((resMu / (resMu + enlMu)) * 100);
+ scoreHtml += ''
+ + window.plugin.scoreboard.percentSpan(resMuPercent, 'res')
+ + window.plugin.scoreboard.percentSpan(100-resMuPercent, 'enl')
+ + '
';
+ }
+
+ scoreHtml += ''
+ + ' | Resistance | Enlightened | Total |
'
+ + window.plugin.scoreboard.teamTableRow('mu','Mu')
+ + window.plugin.scoreboard.teamTableRow('count_fields','Fields')
+ + window.plugin.scoreboard.teamTableRow('count_links','Links')
+ + window.plugin.scoreboard.teamTableRow('count_portals','Portals')
+ + window.plugin.scoreboard.teamTableRow('count_resonators','Resonators')
+ + '
';
+
+ scoreHtml += ''
+ + ' | Resistance | Enlightened |
'
+ + 'Largest Field | '
+ + window.plugin.scoreboard.fieldInfo(scores['team'][TEAM_RES]['largest']['mu'])
+ + ' | '
+ + window.plugin.scoreboard.fieldInfo(scores['team'][TEAM_ENL]['largest']['mu'])
+ + ' |
'
+ + '
';
+
+ scoreHtml += ''
+ + window.plugin.scoreboard.playerTable('mu')
+ + '
';
+
+ scoreHtml += 'Click on player table headers to sort by that column. '
+ + 'Score is subject to portals available based on zoom level. '
+ + 'If names are unresolved try again. For best results wait until updates are fully loaded.
';
+ } else {
+ scoreHtml += 'You need something in view.';
+ }
+
+ alert('' + scoreHtml + '
');
+ $(".ui-dialog").addClass('ui-dialog-scoreboard');
+
+ // Setup sorting
+ $(document).on('click', '#players table th', function() {
+ $('#players').html(window.plugin.scoreboard.playerTable($(this).data('sort')));
+ });
+}
+
+var setup = function() {
+ $('body').append('');
+ $('#toolbox').append('scoreboard');
+ $('head').append('');
+}
+
+// PLUGIN END //////////////////////////////////////////////////////////
+
+if(window.iitcLoaded && typeof setup === 'function') {
+ setup();
+} else {
+ if(window.bootPlugins)
+ window.bootPlugins.push(setup);
+ else
+ window.bootPlugins = [setup];
+}
+} // wrapper end
+// inject code into site context
+var script = document.createElement('script');
+script.appendChild(document.createTextNode('('+ wrapper +')();'));
+(document.body || document.head || document.documentElement).appendChild(script);