This commit is contained in:
Jack Miner 2013-11-07 05:26:42 +00:00
commit c620aae5a7
24 changed files with 1291 additions and 86 deletions

185
code/artifact.js Normal file
View File

@ -0,0 +1,185 @@
// ARTIFACT ///////////////////////////////////////////////////////
// added as part of the ingress #13magnus in november 2013, artifacts
// are additional game elements overlayed on the intel map
// currently there are only jarvis-related entities
// - shards: move between portals (along links) each hour. more than one can be at a portal
// - targets: specific portals - one per team
// the artifact data includes details for the specific portals, so can be useful
window.artifact = function() {}
window.artifact.setup = function() {
artifact.REFRESH_SUCCESS = 15*60; // 15 minutes on success
artifact.REFRESH_FAILURE = 2*60; // 2 minute retry on failure
artifact.idle = false;
artifact.clearData();
addResumeFunction(artifact.idleResume);
artifact.requestData();
artifact._layer = new L.LayerGroup();
addLayerGroup ('Artifacts (Jarvis shards)', artifact._layer, true);
}
window.artifact.requestData = function() {
if (isIdle()) {
artifact.idle = true;
} else {
window.postAjax('getArtifactInfo', {}, artifact.handleSuccess, artifact.handleError);
}
}
window.artifact.idleResume = function() {
if (artifact.idle) {
artifact.idle = false;
artifact.requestData();
}
}
window.artifact.handleSuccess = function(data) {
artifact.processData (data);
setTimeout (artifact.requestData, artifact.REFRESH_SUCCESS*1000);
}
window.artifact.handleFailure = function(data) {
// no useful data on failure - do nothing
setTimeout (artifact.requestData, artifact.REFRESH_FAILURE*1000);
}
window.artifact.processData = function(data) {
if (!data.artifacts) {
console.warn('Failed to find artifacts in artifact response');
return;
}
artifact.clearData();
$.each (data.artifacts, function(i,artData) {
if (artData.artifactId != 'jarvis') {
// jarvis artifacts - fragmentInfos and targetInfos
// (future types? completely unknown at this time!)
console.warn('Note: unknown artifactId '+artData.artifactId+' - guessing how to handle it');
}
if (artData.fragmentInfos) {
artifact.processFragmentInfos (artData.artifactId, artData.fragmentInfos);
}
if (artData.targetInfos) {
artifact.processTargetInfos (artData.artifactId, artData.targetInfos);
}
// other data in future? completely unknown!
});
// redraw the artifact layer
artifact.updateLayer();
}
window.artifact.clearData = function() {
artifact.portalInfo = {};
}
window.artifact.processFragmentInfos = function (id, fragments) {
$.each(fragments, function(i, fragment) {
if (!artifact.portalInfo[fragment.portalGuid]) {
artifact.portalInfo[fragment.portalGuid] = { _entityData: fragment.portalInfo };
}
if (!artifact.portalInfo[fragment.portalGuid][id]) artifact.portalInfo[fragment.portalGuid][id] = {};
if (!artifact.portalInfo[fragment.portalGuid][id].fragments) artifact.portalInfo[fragment.portalGuid][id].fragments = [];
$.each(fragment.fragments, function(i,f) {
artifact.portalInfo[fragment.portalGuid][id].fragments.push(f);
});
});
}
window.artifact.processTargetInfos = function (id, targets) {
$.each(targets, function(i, target) {
if (!artifact.portalInfo[target.portalGuid]) {
artifact.portalInfo[target.portalGuid] = { _entityData: target.portalInfo };
}
if (!artifact.portalInfo[target.portalGuid][id]) artifact.portalInfo[target.portalGuid][id] = {};
artifact.portalInfo[target.portalGuid][id].target = target.team === 'RESISTANCE' ? TEAM_RES : TEAM_ENL;
});
}
// used to render portals that would otherwise be below the visible level
window.artifact.getArtifactEntities = function() {
var entities = [];
// create fake entities from the artifact data
$.each (artifact.portalInfo, function(guid,data) {
var timestamp = 0; // we don't have a valid timestamp - so let's use 0
var ent = [ guid, timestamp, data._entityData ];
entities.push(ent);
});
return entities;
}
window.artifact.updateLayer = function() {
artifact._layer.clearLayers();
// TODO: icons
// //commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/jarvis_shard.png
// //commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/jarvis_shard_target_0.png
// (replace '0' with count of shards at the target portal)
$.each(artifact.portalInfo, function(guid,data) {
var latlng = L.latLng ([data._entityData.locationE6.latE6/1E6, data._entityData.locationE6.lngE6/1E6]);
// jarvis shard icon
var iconUrl = undefined;
var iconSize = 0;
if (data.jarvis.fragments) {
iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/jarvis_shard.png';
iconSize = 60/2; // 60 pixels - half that size works better
}
if (data.jarvis.target) {
// target portal - show the target marker. use the count of fragments at the target to pick the right icon - it has segments that fill up
var count = data.jarvis.fragments ? data.jarvis.fragments.length : 0;
iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/jarvis_shard_target_'+count+'.png';
iconSize = 100/2; // 100 pixels - half that size works better
}
if (iconUrl) {
var icon = L.icon({
iconUrl: iconUrl,
iconSize: [iconSize,iconSize],
iconAnchor: [iconSize/2,iconSize/2],
className: 'no-pointer-events' // the clickable: false below still blocks events going through to the svg underneath
});
var marker = L.marker (latlng, {icon: icon, clickable: false, keyboard: false});
artifact._layer.addLayer(marker);
} else {
console.warn('Oops! no URL for artifact portal icon?!');
}
});
}

View File

@ -525,6 +525,7 @@ function boot() {
window.setupLargeImagePreview();
window.setupSidebarToggle();
window.updateGameScore();
window.artifact.setup();
window.setupPlayerStat();
window.setupTooltips();
window.chat.setup();

View File

@ -213,6 +213,7 @@ window.MapDataRequest.prototype.refresh = function() {
this.render.updateEntityVisibility();
this.render.processGameEntities(artifact.getArtifactEntities());
console.log('requesting data tiles at zoom '+zoom+' (L'+minPortalLevel+'+ portals), map zoom is '+map.getZoom());

647
code/utils_misc.js Normal file
View File

@ -0,0 +1,647 @@
// UTILS + MISC ///////////////////////////////////////////////////////
window.aboutIITC = function() {
var v = (script_info.script && script_info.script.version || script_info.dateTimeVersion) + ' ['+script_info.buildName+']';
if (typeof android !== 'undefined' && android && android.getVersionName) {
v += '[IITC Mobile '+android.getVersionName()+']';
}
var plugins = '<ul>';
for (var i in bootPlugins) {
var info = bootPlugins[i].info;
if (info) {
var pname = info.script && info.script.name || info.pluginId;
if (pname.substr(0,13) == 'IITC plugin: ' || pname.substr(0,13) == 'IITC Plugin: ') {
pname = pname.substr(13);
}
var pvers = info.script && info.script.version || info.dateTimeVersion;
var ptext = pname + ' - ' + pvers;
if (info.buildName != script_info.buildName) {
ptext += ' ['+(info.buildName||'<i>non-standard plugin</i>')+']';
}
plugins += '<li>'+ptext+'</li>';
} else {
// no 'info' property of the plugin setup function - old plugin wrapper code
// could attempt to find the "window.plugin.NAME = function() {};" line it's likely to have..?
plugins += '<li>(unknown plugin: index '+i+')</li>';
}
}
plugins += '</ul>';
var attrib = '@@INCLUDEMD:ATTRIBUTION.md@@';
var contrib = '@@INCLUDEMD:CONTRIBS.md@@'
var a = ''
+ ' <div><b>About IITC</b></div> '
+ ' <div>Ingress Intel Total Conversion</div> '
+ ' <hr>'
+ ' <div>'
+ ' <a href="http://iitc.jonatkins.com/" target="_blank">IITC Homepage</a><br />'
+ ' On the scripts homepage you can:'
+ ' <ul>'
+ ' <li>Find Updates</li>'
+ ' <li>Get Plugins</li>'
+ ' <li>Report Bugs</li>'
+ ' <li>Contribute!</li>'
+ ' </ul>'
+ ' </div>'
+ ' <div>'
+ ' MapQuest OSM tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="https://developer.mapquest.com/content/osm/mq_logo.png">'
+ ' </div>'
+ ' <hr>'
+ ' <div>Version: ' + v + '</div>'
+ ' <div>Plugins: ' + plugins + '</div>'
+ ' <hr>'
+ ' <div>' + attrib + '</div>'
+ ' <hr>'
+ ' <div>' + contrib + '</div>';
dialog({
title: 'IITC ' + v,
html: a,
dialogClass: 'ui-dialog-aboutIITC'
});
}
window.layerGroupLength = function(layerGroup) {
var layersCount = 0;
var layers = layerGroup._layers;
if (layers)
layersCount = Object.keys(layers).length;
return layersCount;
}
// retrieves parameter from the URL?query=string.
window.getURLParam = function(param) {
var v = document.URL;
var i = v.indexOf(param);
if(i <= -1) return '';
v = v.substr(i);
i = v.indexOf("&");
if(i >= 0) v = v.substr(0, i);
return v.replace(param+"=","");
}
// read cookie by name.
// http://stackoverflow.com/a/5639455/1684530 by cwolves
var cookies;
window.readCookie = function(name,c,C,i){
if(cookies) return cookies[name];
c = document.cookie.split('; ');
cookies = {};
for(i=c.length-1; i>=0; i--){
C = c[i].split('=');
cookies[C[0]] = unescape(C[1]);
}
return cookies[name];
}
window.writeCookie = function(name, val) {
document.cookie = name + "=" + val + '; expires=Thu, 31 Dec 2020 23:59:59 GMT; path=/';
}
window.eraseCookie = function(name) {
document.cookie = name + '=; expires=Thu, 1 Jan 1970 00:00:00 GMT; path=/';
}
//certain values were stored in cookies, but we're better off using localStorage instead - make it easy to convert
window.convertCookieToLocalStorage = function(name) {
var cookie=readCookie(name);
if(cookie !== undefined) {
console.log('converting cookie '+name+' to localStorage');
if(localStorage[name] === undefined) {
localStorage[name] = cookie;
}
eraseCookie(name);
}
}
// add thousand separators to given number.
// http://stackoverflow.com/a/1990590/1684530 by Doug Neiner.
window.digits = function(d) {
return (d+"").replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1 ");
}
window.requestParameterMunges = [
// now obsolete (they don't have some of the new parameters) munge sets deleted
// set 6 - 2013-10-29
{
'dashboard.getGameScore': 'vzjhib746rvkre04', // GET_GAME_SCORE
'dashboard.getPaginatedPlextsV2': 'gqa96zhqpddtfmkl', // GET_PAGINATED_PLEXTS
'dashboard.getThinnedEntitiesV4': '18lmw7lytgxji0dk', // GET_THINNED_ENTITIES
'dashboard.getPlayersByGuids': 'emb5xrj8rav1i0be', // LOOKUP_PLAYERS
'dashboard.redeemReward': '4xqof5pldqab63rb', // REDEEM_REWARD
'dashboard.sendInviteEmail': 'yq5wxjlnud0tj6hu', // SEND_INVITE_EMAIL
'dashboard.sendPlext': 'e1ipqdxjlwd3l7zb', // SEND_PLEXT
// common parameters
method: 'wg7gyxoanqc1si5r',
version: 'adlo9o4kjvho5q94', //guessed parameter name - only seen munged
version_parameter: '56036a6497ea344a9fffa38b171a77c092c1f220', // passed as the value to the above parameter
// GET_THINNED_ENTITIES
quadKeys: '6vcl0ivqz4aj5sfu', //guessed parameter name - only seen munged
// GET_PAGINATED_PLEXTS
desiredNumItems: '6jd5b49wn748diye',
minLatE6: '891ebsryg45b8cxb',
minLngE6: 'mvepdcx1k6noya15',
maxLatE6: 's3rh3fhji5mcjlof',
maxLngE6: 'yqdgfuukrxj8byzj',
minTimestampMs: 'btf0kpztxrkt6sl6',
maxTimestampMs: 'hg8vhtehxf53n5cu',
chatTab: '6bk9rmebtk1ux6da', //guessed parameter name - only seen munged
ascendingTimestampOrder: '4zw3v6xwp117r47w',
// SEND_PLEXT
message: '55vpsci0hji0ai5x',
latE6: 'lyhrt4miuwc7w29d',
lngE6: 'c1yl2qmzfu5j23ao',
// chatTab: '6bk9rmebtk1ux6da', //guessed parameter name - only seen munged
// LOOKUP_PLAYERS
guids: 'k76phw8ey9z21z7c',
// SEND_INVITE_EMAIL
inviteeEmailAddress: 'x16pe9u4i8bidbi2',
},
// set 7 - 2013-11-06
{
'dashboard.getArtifactInfo': 'artifacts', // GET_ARTIFACT_INFO: new (and not obfsucated?!)
'dashboard.getGameScore': 'yol4dxx5ufqolhk2', // GET_GAME_SCORE
'dashboard.getPaginatedPlextsV2': '7b83j2z81rtk6101', // GET_PAGINATED_PLEXTS
'dashboard.getThinnedEntitiesV4': '46su4lrisoq28gxh', // GET_THINNED_ENTITIES
'dashboard.getPlayersByGuids': 'wsc5puahrymtf1qh', // LOOKUP_PLAYERS
'dashboard.redeemReward': 'oo0n7pw2m0xufpzx', // REDEEM_REWARD
'dashboard.sendInviteEmail': 'bo1bp74rz8kbdjkb', // SEND_INVITE_EMAIL
'dashboard.sendPlext': 'q0f8o4v9t8pt91yv', // SEND_PLEXT
// common parameters
method: 'imo60cdzkemxduub',
version: '54lh4o0q7nz7dao9', //guessed parameter name - only seen munged
version_parameter: '370c0b4e160ed26c8c4ce40f10f546545730e1ef', // passed as the value to the above parameter
// GET_THINNED_ENTITIES
quadKeys: 'iqy8e2d3zpne0cmh', //guessed parameter name - only seen munged
// GET_PAGINATED_PLEXTS
desiredNumItems: 'chwe3yko3xy0qlk3',
minLatE6: 'f31z3x27ua8i05cf',
minLngE6: 't0rmob7f42c0w04r',
maxLatE6: 'ebwfvri5io9q0tvu',
maxLngE6: 'lfqzvpj92dp8uxo6',
minTimestampMs: '23a6djyyieeaeduu',
maxTimestampMs: 'zhjtsm2gw7w3b7mx',
chatTab: 'tak64gipm3hhqpnh', //guessed parameter name - only seen munged
ascendingTimestampOrder: 'v5rzzxtg5rmry3dx',
// SEND_PLEXT
message: 'onptntn3szan21lj',
latE6: '1jq9lgu3hjajrt7s',
lngE6: 'plbubiopnavbxxh6',
// chatTab: 'tak64gipm3hhqpnh', //guessed parameter name - only seen munged
// LOOKUP_PLAYERS
guids: '919p2cfpdo2wz03n',
// SEND_INVITE_EMAIL
inviteeEmailAddress: 'thpbnoyjx0antwm5',
},
];
window.activeRequestMungeSet = undefined;
// attempt to guess the munge set in use, by looking therough the functions of the stock intel page for one of the munged params
window.detectActiveMungeSet = function() {
// try and find the stock page functions
// FIXME? revert to searching through all the code? is that practical?
var stockFunc;
try {
stockFunc = nemesis.dashboard.network.XhrController.prototype.sendRequest.toString();
} catch(e) {
try {
stockFunc = nemesis.dashboard.network.DataFetcher.prototype.sendRequest_.toString();
} catch(e) {
}
}
if(stockFunc) {
for (var i in window.requestParameterMunges) {
if (stockFunc.indexOf (window.requestParameterMunges[i]['method']) >= 0) {
console.log('IITC: found request munge set index '+i+' in stock intel site');
window.activeRequestMungeSet = i;
}
}
} else {
console.error('IITC: failed to find the stock site function for detecting munge set');
}
if (window.activeRequestMungeSet===undefined) {
console.error('IITC: failed to find request munge set - IITC will likely fail');
window.activeRequestMungeSet = 0;
}
}
// niantic now add some munging to the request parameters. so far, only two sets of this munging have been seen
window.requestDataMunge = function(data) {
var activeMunge = window.requestParameterMunges[window.activeRequestMungeSet];
function munge(obj) {
if (Object.prototype.toString.call(obj) === '[object Array]') {
// an array - munge each element of it
var newobj = [];
for (var i in obj) {
newobj[i] = munge(obj[i]);
}
return newobj;
} else if (typeof obj === 'object') {
// an object: munge each property name, and pass the value through the munge process
var newobj = Object();
for (var p in obj) {
var m = activeMunge[p];
if (m === undefined) {
console.error('Error: failed to find munge for object property '+p);
newobj[p] = obj[p];
} else {
// rename the property
newobj[m] = munge(obj[p]);
}
}
return newobj;
} else {
// neither an array or an object - so must be a simple value. return it unmodified
return obj;
}
};
var newdata = munge(data);
return newdata;
}
// posts AJAX request to Ingress API.
// action: last part of the actual URL, the rpc/dashboard. is
// added automatically
// data: JSON data to post. method will be derived automatically from
// action, but may be overridden. Expects to be given Hash.
// Strings are not supported.
// success: method to call on success. See jQuery API docs for avail-
// able arguments: http://api.jquery.com/jQuery.ajax/
// error: see above. Additionally it is logged if the request failed.
window.postAjax = function(action, data, success, error) {
if (window.activeRequestMungeSet===undefined) {
window.detectActiveMungeSet();
}
var activeMunge = window.requestParameterMunges[window.activeRequestMungeSet];
var methodName = 'dashboard.'+action;
var versionStr = 'version_parameter';
// munging of the method name - seen in Set 2 (onwards?)
methodName = activeMunge[methodName];
// and of the 'version' parameter
versionStr = activeMunge[versionStr];
var post_data = JSON.stringify(window.requestDataMunge($.extend({method: methodName, version: versionStr}, data)));
var remove = function(data, textStatus, jqXHR) { window.requests.remove(jqXHR); };
var errCnt = function(jqXHR) { window.failedRequestCount++; window.requests.remove(jqXHR); };
var result = $.ajax({
url: '/r/'+methodName,
type: 'POST',
data: post_data,
context: data,
dataType: 'json',
success: [remove, success],
error: error ? [errCnt, error] : errCnt,
contentType: 'application/json; charset=utf-8',
beforeSend: function(req) {
req.setRequestHeader('X-CSRFToken', readCookie('csrftoken'));
}
});
result.action = action;
return result;
}
window.zeroPad = function(number,pad) {
number = number.toString();
var zeros = pad - number.length;
return Array(zeros>0?zeros+1:0).join("0") + number;
}
// converts javascript timestamps to HH:mm:ss format if it was today;
// otherwise it returns YYYY-MM-DD
window.unixTimeToString = function(time, full) {
if(!time) return null;
var d = new Date(typeof time === 'string' ? parseInt(time) : time);
var time = d.toLocaleTimeString();
var date = d.getFullYear()+'-'+zeroPad(d.getMonth()+1,2)+'-'+zeroPad(d.getDate(),2);
if(typeof full !== 'undefined' && full) return date + ' ' + time;
if(d.toDateString() == new Date().toDateString())
return time;
else
return date;
}
// converts a javascript time to a precise date and time (optionally with millisecond precision)
// formatted in ISO-style YYYY-MM-DD hh:mm:ss.mmm - but using local timezone
window.unixTimeToDateTimeString = function(time, millisecond) {
if(!time) return null;
var d = new Date(typeof time === 'string' ? parseInt(time) : time);
return d.getFullYear()+'-'+zeroPad(d.getMonth()+1,2)+'-'+zeroPad(d.getDate(),2)
+' '+d.toLocaleTimeString()+(millisecond?'.'+zeroPad(d.getMilliseconds(),3):'');
}
window.unixTimeToHHmm = function(time) {
if(!time) return null;
var d = new Date(typeof time === 'string' ? parseInt(time) : time);
var h = '' + d.getHours(); h = h.length === 1 ? '0' + h : h;
var s = '' + d.getMinutes(); s = s.length === 1 ? '0' + s : s;
return h + ':' + s;
}
window.formatInterval = function(seconds) {
var h = Math.floor(seconds / 3600);
var m = Math.floor((seconds % 3600) / 60);
var s = seconds % 60;
var text = '';
if (h > 0) text += h+'h';
if (m > 0) text += m+'m';
if (s > 0 || text == '') text += s+'s';
return text;
}
window.rangeLinkClick = function() {
if(window.portalRangeIndicator)
window.map.fitBounds(window.portalRangeIndicator.getBounds());
if(window.isSmartphone())
window.show('map');
}
window.showPortalPosLinks = function(lat, lng, name) {
var encoded_name = 'undefined';
if(name !== undefined) {
encoded_name = encodeURIComponent(name);
}
if (typeof android !== 'undefined' && android && android.intentPosLink) {
android.intentPosLink(lat, lng, map.getZoom(), name, true);
} else {
var qrcode = '<div id="qrcode"></div>';
var script = '<script>$(\'#qrcode\').qrcode({text:\'GEO:'+lat+','+lng+'\'});</script>';
var gmaps = '<a href="https://maps.google.com/?q='+lat+','+lng+'%20('+encoded_name+')">Google Maps</a>';
var bingmaps = '<a href="http://www.bing.com/maps/?v=2&cp='+lat+'~'+lng+'&lvl=16&sp=Point.'+lat+'_'+lng+'_'+encoded_name+'___">Bing Maps</a>';
var osm = '<a href="http://www.openstreetmap.org/?mlat='+lat+'&mlon='+lng+'&zoom=16">OpenStreetMap</a>';
var latLng = '<span>&lt;' + lat + ',' + lng +'&gt;</span>';
dialog({
html: '<div style="text-align: center;">' + qrcode + script + gmaps + '; ' + bingmaps + '; ' + osm + '<br />' + latLng + '</div>',
title: name,
id: 'poslinks'
});
}
}
window.androidCopy = function(text) {
if(typeof android === 'undefined' || !android || !android.copy)
return true; // i.e. execute other actions
else
android.copy(text);
return false;
}
window.androidPermalink = function() {
if(typeof android === 'undefined' || !android || !android.copy)
return true; // i.e. execute other actions
var center = map.getCenter();
android.intentPosLink(center.lat, center.lng, map.getZoom(), "Intel Map", false);
return false;
}
window.getPortalDataZoom = function() {
var mapZoom = map.getZoom();
// make sure we're dealing with an integer here
// (mobile: a float somehow gets through in some cases!)
var z = parseInt(mapZoom);
// limiting the mazimum zoom level for data retrieval reduces the number of requests at high zoom levels
// (as all portal data is retrieved at z=17, why retrieve multiple z=18 tiles when fewer z=17 would do?)
// very effective along with the new cache code
if (z > 17) z=17;
//sanity check - should never happen
if (z < 0) z=0;
return z;
}
window.getMinPortalLevelForZoom = function(z) {
//based on code from stock gen_dashboard.js
var ZOOM_TO_LEVEL = [8, 8, 8, 8, 7, 7, 6, 6, 5, 4, 4, 3, 3, 2, 2, 1, 1];
var l = ZOOM_TO_LEVEL[z] || 0;
return l;
}
window.getMinPortalLevel = function() {
var z = getPortalDataZoom();
return getMinPortalLevelForZoom(z);
}
// returns number of pixels left to scroll down before reaching the
// bottom. Works similar to the native scrollTop function.
window.scrollBottom = function(elm) {
if(typeof elm === 'string') elm = $(elm);
return elm.get(0).scrollHeight - elm.innerHeight() - elm.scrollTop();
}
window.zoomToAndShowPortal = function(guid, latlng) {
map.setView(latlng, 17);
// if the data is available, render it immediately. Otherwise defer
// until it becomes available.
if(window.portals[guid])
renderPortalDetails(guid);
else
urlPortal = guid;
}
String.prototype.capitalize = function() {
return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase();
}
// http://stackoverflow.com/a/646643/1684530 by Bergi and CMS
if (typeof String.prototype.startsWith !== 'function') {
String.prototype.startsWith = function (str){
return this.slice(0, str.length) === str;
};
}
// escape a javascript string, so quotes and backslashes are escaped with a backslash
// (for strings passed as parameters to html onclick="..." for example)
window.escapeJavascriptString = function(str) {
return (str+'').replace(/[\\"']/g,'\\$&');
}
//escape special characters, such as tags
window.escapeHtmlSpecialChars = function(str) {
var div = document.createElement(div);
var text = document.createTextNode(str);
div.appendChild(text);
return div.innerHTML;
}
window.prettyEnergy = function(nrg) {
return nrg> 1000 ? Math.round(nrg/1000) + ' k': nrg;
}
window.setPermaLink = function(elm) {
var c = map.getCenter();
var lat = Math.round(c.lat*1E6)/1E6;
var lng = Math.round(c.lng*1E6)/1E6;
var qry = 'll='+lat+','+lng+'&z=' + map.getZoom();
$(elm).attr('href', '/intel?' + qry);
}
window.uniqueArray = function(arr) {
return $.grep(arr, function(v, i) {
return $.inArray(v, arr) === i;
});
}
window.genFourColumnTable = function(blocks) {
var t = $.map(blocks, function(detail, index) {
if(!detail) return '';
if(index % 2 === 0)
return '<tr><td>'+detail[1]+'</td><th>'+detail[0]+'</th>';
else
return ' <th>'+detail[0]+'</th><td>'+detail[1]+'</td></tr>';
}).join('');
if(t.length % 2 === 1) t + '<td></td><td></td></tr>';
return t;
}
// converts given text with newlines (\n) and tabs (\t) to a HTML
// table automatically.
window.convertTextToTableMagic = function(text) {
// check if it should be converted to a table
if(!text.match(/\t/)) return text.replace(/\n/g, '<br>');
var data = [];
var columnCount = 0;
// parse data
var rows = text.split('\n');
$.each(rows, function(i, row) {
data[i] = row.split('\t');
if(data[i].length > columnCount) columnCount = data[i].length;
});
// build the table
var table = '<table>';
$.each(data, function(i, row) {
table += '<tr>';
$.each(data[i], function(k, cell) {
var attributes = '';
if(k === 0 && data[i].length < columnCount) {
attributes = ' colspan="'+(columnCount - data[i].length + 1)+'"';
}
table += '<td'+attributes+'>'+cell+'</td>';
});
table += '</tr>';
});
table += '</table>';
return table;
}
// Given 3 sets of points in an array[3]{lat, lng} returns the area of the triangle
window.calcTriArea = function(p) {
return Math.abs((p[0].lat*(p[1].lng-p[2].lng)+p[1].lat*(p[2].lng-p[0].lng)+p[2].lat*(p[0].lng-p[1].lng))/2);
}
// Update layerGroups display status to window.overlayStatus and localStorage 'ingress.intelmap.layergroupdisplayed'
window.updateDisplayedLayerGroup = function(name, display) {
overlayStatus[name] = display;
localStorage['ingress.intelmap.layergroupdisplayed'] = JSON.stringify(overlayStatus);
}
// Read layerGroup status from window.overlayStatus if it was added to map,
// read from cookie if it has not added to map yet.
// return 'defaultDisplay' if both overlayStatus and cookie didn't have the record
window.isLayerGroupDisplayed = function(name, defaultDisplay) {
if(typeof(overlayStatus[name]) !== 'undefined') return overlayStatus[name];
convertCookieToLocalStorage('ingress.intelmap.layergroupdisplayed');
var layersJSON = localStorage['ingress.intelmap.layergroupdisplayed'];
if(!layersJSON) return defaultDisplay;
var layers = JSON.parse(layersJSON);
// keep latest overlayStatus
overlayStatus = $.extend(layers, overlayStatus);
if(typeof(overlayStatus[name]) === 'undefined') return defaultDisplay;
return overlayStatus[name];
}
window.addLayerGroup = function(name, layerGroup, defaultDisplay) {
if(isLayerGroupDisplayed(name, defaultDisplay)) map.addLayer(layerGroup);
layerChooser.addOverlay(layerGroup, name);
}
window.clampLat = function(lat) {
// the map projection used does not handle above approx +- 85 degrees north/south of the equator
if (lat > 85.051128)
lat = 85.051128;
else if (lat < -85.051128)
lat = -85.051128;
return lat;
}
window.clampLng = function(lng) {
if (lng > 179.999999)
lng = 179.999999;
else if (lng < -180.0)
lng = -180.0;
return lng;
}
window.clampLatLng = function(latlng) {
return new L.LatLng ( clampLat(latlng.lat), clampLng(latlng.lng) );
}
window.clampLatLngBounds = function(bounds) {
return new L.LatLngBounds ( clampLatLng(bounds.getSouthWest()), clampLatLng(bounds.getNorthEast()) );
}
// avoid error in stock JS
if(goog && goog.style) {
goog.style.showElement = function(a, b) {
if(a && a.style)
a.style.display = b ? "" : "none"
};
}
// Fix Leaflet: handle touchcancel events in Draggable
L.Draggable.prototype._onDownOrig = L.Draggable.prototype._onDown;
L.Draggable.prototype._onDown = function(e) {
L.Draggable.prototype._onDownOrig.apply(this, arguments);
if(e.type === "touchstart") {
L.DomEvent.on(document, "touchcancel", this._onUp, this);
}
}

22
external/oms.min.js vendored
View File

@ -5,15 +5,15 @@ Copyright (c) 2011 - 2012 George MacKerron
Released under the MIT licence: http://opensource.org/licenses/mit-license
Note: The Leaflet maps API must be included *before* this code
*/
(function(){var n={}.hasOwnProperty,o=[].slice;null!=this.L&&(this.OverlappingMarkerSpiderfier=function(){function l(c,b){var a,e,g,f,d=this;this.map=c;null==b&&(b={});for(a in b)n.call(b,a)&&(e=b[a],this[a]=e);this.initMarkerArrays();this.listeners={};f=["click","zoomend"];e=0;for(g=f.length;e<g;e++)a=f[e],this.map.addEventListener(a,function(){return d.unspiderfy()})}var d,i;d=l.prototype;d.VERSION="0.2.5";i=2*Math.PI;d.keepSpiderfied=!1;d.nearbyDistance=20;d.circleSpiralSwitchover=9;d.circleFootSeparation=
25;d.circleStartAngle=i/12;d.spiralFootSeparation=28;d.spiralLengthStart=11;d.spiralLengthFactor=5;d.legWeight=1.5;d.legColors={usual:"#222",highlighted:"#f00"};d.initMarkerArrays=function(){this.markers=[];return this.markerListeners=[]};d.addMarker=function(c){var b,a=this;if(null!=c._oms)return this;c._oms=!0;b=function(){return a.spiderListener(c)};c.addEventListener("click",b);this.markerListeners.push(b);this.markers.push(c);return this};d.getMarkers=function(){return this.markers.slice(0)};
(function(){var q={}.hasOwnProperty,r=[].slice;null!=this.L&&(this.OverlappingMarkerSpiderfier=function(){function n(c,b){var a,e,g,f,d=this;this.map=c;null==b&&(b={});for(a in b)q.call(b,a)&&(e=b[a],this[a]=e);this.initMarkerArrays();this.listeners={};f=["click","zoomend"];e=0;for(g=f.length;e<g;e++)a=f[e],this.map.addEventListener(a,function(){return d.unspiderfy()})}var d,k;d=n.prototype;d.VERSION="0.2.6";k=2*Math.PI;d.keepSpiderfied=!1;d.nearbyDistance=20;d.circleSpiralSwitchover=9;d.circleFootSeparation=
25;d.circleStartAngle=k/12;d.spiralFootSeparation=28;d.spiralLengthStart=11;d.spiralLengthFactor=5;d.legWeight=1.5;d.legColors={usual:"#222",highlighted:"#f00"};d.initMarkerArrays=function(){this.markers=[];return this.markerListeners=[]};d.addMarker=function(c){var b,a=this;if(null!=c._oms)return this;c._oms=!0;b=function(){return a.spiderListener(c)};c.addEventListener("click",b);this.markerListeners.push(b);this.markers.push(c);return this};d.getMarkers=function(){return this.markers.slice(0)};
d.removeMarker=function(c){var b,a;null!=c._omsData&&this.unspiderfy();b=this.arrIndexOf(this.markers,c);if(0>b)return this;a=this.markerListeners.splice(b,1)[0];c.removeEventListener("click",a);delete c._oms;this.markers.splice(b,1);return this};d.clearMarkers=function(){var c,b,a,e,g;this.unspiderfy();g=this.markers;c=a=0;for(e=g.length;a<e;c=++a)b=g[c],c=this.markerListeners[c],b.removeEventListener("click",c),delete b._oms;this.initMarkerArrays();return this};d.addListener=function(c,b){var a,
e;(null!=(e=(a=this.listeners)[c])?e:a[c]=[]).push(b);return this};d.removeListener=function(c,b){var a;a=this.arrIndexOf(this.listeners[c],b);0>a||this.listeners[c].splice(a,1);return this};d.clearListeners=function(c){this.listeners[c]=[];return this};d.trigger=function(){var c,b,a,e,g,f;b=arguments[0];c=2<=arguments.length?o.call(arguments,1):[];b=null!=(a=this.listeners[b])?a:[];f=[];e=0;for(g=b.length;e<g;e++)a=b[e],f.push(a.apply(null,c));return f};d.generatePtsCircle=function(c,b){var a,e,
g,f,d;g=this.circleFootSeparation*(2+c)/i;e=i/c;d=[];for(a=f=0;0<=c?f<c:f>c;a=0<=c?++f:--f)a=this.circleStartAngle+a*e,d.push(new L.Point(b.x+g*Math.cos(a),b.y+g*Math.sin(a)));return d};d.generatePtsSpiral=function(c,b){var a,e,g,f,d;g=this.spiralLengthStart;a=0;d=[];for(e=f=0;0<=c?f<c:f>c;e=0<=c?++f:--f)a+=this.spiralFootSeparation/g+5.0E-4*e,e=new L.Point(b.x+g*Math.cos(a),b.y+g*Math.sin(a)),g+=i*this.spiralLengthFactor/a,d.push(e);return d};d.spiderListener=function(c){var b,a,e,g,f,d,h,i,j;b=
null!=c._omsData;(!b||!this.keepSpiderfied)&&this.unspiderfy();if(b)return this.trigger("click",c);g=[];f=[];d=this.nearbyDistance*this.nearbyDistance;e=this.map.latLngToLayerPoint(c.getLatLng());j=this.markers;h=0;for(i=j.length;h<i;h++)b=j[h],a=this.map.latLngToLayerPoint(b.getLatLng()),this.ptDistanceSq(a,e)<d?g.push({marker:b,markerPt:a}):f.push(b);return 1===g.length?this.trigger("click",c):this.spiderfy(g,f)};d.makeHighlightListeners=function(c){var b=this;return{highlight:function(){return c._omsData.leg.setStyle({color:b.legColors.highlighted})},
unhighlight:function(){return c._omsData.leg.setStyle({color:b.legColors.usual})}}};d.spiderfy=function(c,b){var a,e,g,d,m,h,i,j,l,k;this.spiderfying=!0;k=c.length;a=this.ptAverage(function(){var a,b,e;e=[];a=0;for(b=c.length;a<b;a++)i=c[a],e.push(i.markerPt);return e}());d=k>=this.circleSpiralSwitchover?this.generatePtsSpiral(k,a).reverse():this.generatePtsCircle(k,a);a=function(){var a,b,i,k=this;i=[];a=0;for(b=d.length;a<b;a++)g=d[a],e=this.map.layerPointToLatLng(g),l=this.minExtract(c,function(a){return k.ptDistanceSq(a.markerPt,
g)}),h=l.marker,m=new L.Polyline([h.getLatLng(),e],{color:this.legColors.usual,weight:this.legWeight,clickable:!1}),this.map.addLayer(m),h._omsData={usualPosition:h.getLatLng(),leg:m},this.legColors.highlighted!==this.legColors.usual&&(j=this.makeHighlightListeners(h),h._omsData.highlightListeners=j,h.addEventListener("mouseover",j.highlight),h.addEventListener("mouseout",j.unhighlight)),h.setLatLng(e),h.setZIndexOffset(1E6),i.push(h);return i}.call(this);delete this.spiderfying;this.spiderfied=!0;
return this.trigger("spiderfy",a,b)};d.unspiderfy=function(c){var b,a,e,d,f,i,h;null==c&&(c=null);if(null==this.spiderfied)return this;this.unspiderfying=!0;d=[];e=[];h=this.markers;f=0;for(i=h.length;f<i;f++)b=h[f],null!=b._omsData?(this.map.removeLayer(b._omsData.leg),b!==c&&b.setLatLng(b._omsData.usualPosition),b.setZIndexOffset(0),a=b._omsData.highlightListeners,null!=a&&(b.removeEventListener("mouseover",a.highlight),b.removeEventListener("mouseout",a.unhighlight)),delete b._omsData,d.push(b)):
e.push(b);delete this.unspiderfying;delete this.spiderfied;this.trigger("unspiderfy",d,e);return this};d.ptDistanceSq=function(c,b){var a,e;a=c.x-b.x;e=c.y-b.y;return a*a+e*e};d.ptAverage=function(c){var b,a,e,d,f;d=a=e=0;for(f=c.length;d<f;d++)b=c[d],a+=b.x,e+=b.y;c=c.length;return new L.Point(a/c,e/c)};d.minExtract=function(c,b){var a,d,g,f,i,h;g=i=0;for(h=c.length;i<h;g=++i)if(f=c[g],f=b(f),!("undefined"!==typeof a&&null!==a)||f<d)d=f,a=g;return c.splice(a,1)[0]};d.arrIndexOf=function(c,b){var a,
d,g,f;if(null!=c.indexOf)return c.indexOf(b);a=g=0;for(f=c.length;g<f;a=++g)if(d=c[a],d===b)return a;return-1};return l}())}).call(this);}).call(this);
/* Sun 6 May 2012 17:49:10 BST */
e;(null!=(e=(a=this.listeners)[c])?e:a[c]=[]).push(b);return this};d.removeListener=function(c,b){var a;a=this.arrIndexOf(this.listeners[c],b);0>a||this.listeners[c].splice(a,1);return this};d.clearListeners=function(c){this.listeners[c]=[];return this};d.trigger=function(){var c,b,a,e,g,f;b=arguments[0];c=2<=arguments.length?r.call(arguments,1):[];b=null!=(a=this.listeners[b])?a:[];f=[];e=0;for(g=b.length;e<g;e++)a=b[e],f.push(a.apply(null,c));return f};d.generatePtsCircle=function(c,b){var a,e,
g,f,d;g=this.circleFootSeparation*(2+c)/k;e=k/c;d=[];for(a=f=0;0<=c?f<c:f>c;a=0<=c?++f:--f)a=this.circleStartAngle+a*e,d.push(new L.Point(b.x+g*Math.cos(a),b.y+g*Math.sin(a)));return d};d.generatePtsSpiral=function(c,b){var a,e,g,f,d;g=this.spiralLengthStart;a=0;d=[];for(e=f=0;0<=c?f<c:f>c;e=0<=c?++f:--f)a+=this.spiralFootSeparation/g+5E-4*e,e=new L.Point(b.x+g*Math.cos(a),b.y+g*Math.sin(a)),g+=k*this.spiralLengthFactor/a,d.push(e);return d};d.spiderListener=function(c){var b,a,e,g,f,d,h,k,l;(b=null!=
c._omsData)&&this.keepSpiderfied||this.unspiderfy();if(b)return this.trigger("click",c);g=[];f=[];d=this.nearbyDistance*this.nearbyDistance;e=this.map.latLngToLayerPoint(c.getLatLng());l=this.markers;h=0;for(k=l.length;h<k;h++)b=l[h],this.map.hasLayer(b)&&(a=this.map.latLngToLayerPoint(b.getLatLng()),this.ptDistanceSq(a,e)<d?g.push({marker:b,markerPt:a}):f.push(b));return 1===g.length?this.trigger("click",c):this.spiderfy(g,f)};d.makeHighlightListeners=function(c){var b=this;return{highlight:function(){return c._omsData.leg.setStyle({color:b.legColors.highlighted})},
unhighlight:function(){return c._omsData.leg.setStyle({color:b.legColors.usual})}}};d.spiderfy=function(c,b){var a,e,g,d,p,h,k,l,n,m;this.spiderfying=!0;m=c.length;a=this.ptAverage(function(){var a,b,e;e=[];a=0;for(b=c.length;a<b;a++)k=c[a],e.push(k.markerPt);return e}());d=m>=this.circleSpiralSwitchover?this.generatePtsSpiral(m,a).reverse():this.generatePtsCircle(m,a);a=function(){var a,b,k,m=this;k=[];a=0;for(b=d.length;a<b;a++)g=d[a],e=this.map.layerPointToLatLng(g),n=this.minExtract(c,function(a){return m.ptDistanceSq(a.markerPt,
g)}),h=n.marker,p=new L.Polyline([h.getLatLng(),e],{color:this.legColors.usual,weight:this.legWeight,clickable:!1}),this.map.addLayer(p),h._omsData={usualPosition:h.getLatLng(),leg:p},this.legColors.highlighted!==this.legColors.usual&&(l=this.makeHighlightListeners(h),h._omsData.highlightListeners=l,h.addEventListener("mouseover",l.highlight),h.addEventListener("mouseout",l.unhighlight)),h.setLatLng(e),h.setZIndexOffset(1E6),k.push(h);return k}.call(this);delete this.spiderfying;this.spiderfied=!0;
return this.trigger("spiderfy",a,b)};d.unspiderfy=function(c){var b,a,e,d,f,k,h;null==c&&(c=null);if(null==this.spiderfied)return this;this.unspiderfying=!0;d=[];e=[];h=this.markers;f=0;for(k=h.length;f<k;f++)b=h[f],null!=b._omsData?(this.map.removeLayer(b._omsData.leg),b!==c&&b.setLatLng(b._omsData.usualPosition),b.setZIndexOffset(0),a=b._omsData.highlightListeners,null!=a&&(b.removeEventListener("mouseover",a.highlight),b.removeEventListener("mouseout",a.unhighlight)),delete b._omsData,d.push(b)):
e.push(b);delete this.unspiderfying;delete this.spiderfied;this.trigger("unspiderfy",d,e);return this};d.ptDistanceSq=function(c,b){var a,e;a=c.x-b.x;e=c.y-b.y;return a*a+e*e};d.ptAverage=function(c){var b,a,e,d,f;d=a=e=0;for(f=c.length;d<f;d++)b=c[d],a+=b.x,e+=b.y;c=c.length;return new L.Point(a/c,e/c)};d.minExtract=function(c,b){var a,d,g,f,k,h;g=k=0;for(h=c.length;k<h;g=++k)if(f=c[g],f=b(f),"undefined"===typeof a||null===a||f<d)d=f,a=g;return c.splice(a,1)[0]};d.arrIndexOf=function(c,b){var a,
d,g,f;if(null!=c.indexOf)return c.indexOf(b);a=g=0;for(f=c.length;g<f;a=++g)if(d=c[a],d===b)return a;return-1};return n}())}).call(this);}).call(this);
/* Mon 14 Oct 2013 10:54:59 BST */

View File

@ -1,7 +1,7 @@
// ==UserScript==
// @id ingress-intel-total-conversion@jonatkins
// @name IITC: Ingress intel map total conversion
// @version 0.14.5.@@DATETIMEVERSION@@
// @version 0.15.0.@@DATETIMEVERSION@@
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL @@UPDATEURL@@
// @downloadURL @@DOWNLOADURL@@

18
mobile/.idea/misc.xml generated
View File

@ -10,24 +10,8 @@
</map>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="Android 4.3 Platform" project-jdk-type="Android SDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="Android 4.4 Platform" project-jdk-type="Android SDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="masterDetails">
<states>
<state key="ProjectJDKs.UI">
<settings>
<last-edited>Android 4.3 Platform</last-edited>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
</states>
</component>
</project>

View File

@ -2,12 +2,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cradle.iitc_mobile"
android:installLocation="auto"
android:versionCode="58"
android:versionName="0.8">
android:versionCode="59"
android:versionName="0.9">
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="18"/>
android:targetSdkVersion="19"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
@ -23,7 +23,7 @@
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="com.cradle.iitc_mobile.IITC_Mobile"
android:name=".IITC_Mobile"
android:configChanges="orientation|keyboard|keyboardHidden|screenSize"
android:label="@string/app_name"
android:launchMode="singleTop"
@ -89,11 +89,11 @@
android:name=".share.ShareActivity"
android:label="@string/activity_share"
android:noHistory="true"
android:parentActivityName="com.cradle.iitc_mobile.IITC_Mobile"
android:parentActivityName=".IITC_Mobile"
android:theme="@android:style/Theme.Holo.Light.DarkActionBar">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.cradle.iitc_mobile.IITC_Mobile"/>
android:value=".IITC_Mobile"/>
</activity>
<activity
@ -136,7 +136,7 @@
<!-- Points to searchable activity so the whole app can invoke search. -->
<meta-data
android:name="android.app.default_searchable"
android:value="com.cradle.iitc_mobile.IITC_Mobile"/>
android:value=".IITC_Mobile"/>
</application>
</manifest>

View File

@ -1,7 +1,7 @@
// ==UserScript==
// @id iitc-plugin-user-location@cradle
// @name IITC plugin: User Location
// @version 0.1.3.@@DATETIMEVERSION@@
// @version 0.1.4.@@DATETIMEVERSION@@
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL @@UPDATEURL@@
// @downloadURL @@DOWNLOADURL@@
@ -35,10 +35,11 @@ window.plugin.userLocation.setup = function() {
var title = '<span class="nickname '+ cssClass+'" style="font-weight:bold;">' + PLAYER.nickname + '</span>\'s location';
var marker = L.marker(window.map.getCenter(), {
title: title,
icon: new plugin.userLocation.icon()
});
marker.bindPopup(title);
plugin.userLocation.marker = marker;
marker.addTo(window.map);
// jQueryUI doesnt automatically notice the new markers

View File

@ -11,4 +11,4 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-18
target=android-19

View File

@ -104,6 +104,11 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity {
}
}
@Override
protected boolean isValidFragment(String s) {
return true;
}
// called by Plugins Fragment
public static ArrayList<IITC_PluginPreference> getPluginPreference(String key) {
return sPlugins.get(key);

View File

@ -16,6 +16,7 @@ import android.view.View;
import android.view.WindowManager;
import android.webkit.ConsoleMessage;
import android.webkit.GeolocationPermissions;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
@ -138,24 +139,9 @@ public class IITC_WebView extends WebView {
@Override
public void loadUrl(String url) {
// if in edit text mode, don't load javascript otherwise the keyboard closes.
HitTestResult testResult = getHitTestResult();
if (url.startsWith("javascript:") && testResult != null &&
testResult.getType() == HitTestResult.EDIT_TEXT_TYPE) {
// let window.show(...) interupt input
// window.show(...) is called if one of the action bar buttons
// is clicked
if (!url.startsWith("javascript: window.show(")) {
Log.d("iitcm", "in insert mode. do not load script.");
return;
}
}
// do nothing if script is enabled;
if (mDisableJs) {
Log.d("iitcm", "javascript injection disabled...return");
return;
}
if (!url.startsWith("javascript:")) {
if (url.startsWith("javascript:")) {
loadJS(url.substring("javascript:".length()));
} else {
// force https if enabled in settings
SharedPreferences sharedPref = PreferenceManager
.getDefaultSharedPreferences(getContext());
@ -168,8 +154,38 @@ public class IITC_WebView extends WebView {
// disable splash screen if a http error code is responded
new CheckHttpResponse(mJsInterface, mIitc).execute(url);
Log.d("iitcm", "loading url: " + url);
super.loadUrl(url);
}
}
public void loadJS(String js) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
evaluateJavascript(js, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
// maybe we want to add stuff here
return;
}
});
} else {
// if in edit text mode, don't load javascript otherwise the keyboard closes.
HitTestResult testResult = getHitTestResult();
if (testResult != null && testResult.getType() == HitTestResult.EDIT_TEXT_TYPE) {
// let window.show(...) interupt input
// window.show(...) is called if one of the action bar buttons
// is clicked
if (!js.startsWith("window.show(")) {
Log.d("iitcm", "in insert mode. do not load script.");
return;
}
}
// do nothing if script is enabled;
if (mDisableJs) {
Log.d("iitcm", "javascript injection disabled...return");
return;
}
super.loadUrl("javascript:" + js);
}
super.loadUrl(url);
}
@Override

View File

@ -43,6 +43,7 @@ public class IITC_WebViewClient extends WebViewClient {
private String mIitcScript = null;
private String mIitcPath = null;
private boolean mIitcInjected = false;
private final Context mContext;
public IITC_WebViewClient(Context c) {
@ -142,6 +143,7 @@ public class IITC_WebViewClient extends WebViewClient {
} else {
js = this.fileToString("total-conversion-build.user.js", true);
}
mIitcInjected = false;
}
PackageManager pm = mContext.getPackageManager();
@ -177,8 +179,10 @@ public class IITC_WebViewClient extends WebViewClient {
public void onPageFinished(WebView view, String url) {
if (url.startsWith("http://www.ingress.com/intel")
|| url.startsWith("https://www.ingress.com/intel")) {
if (mIitcInjected) return;
Log.d("iitcm", "injecting iitc..");
view.loadUrl("javascript: " + this.mIitcScript);
mIitcInjected = true;
loadPlugins(view);
}
super.onPageFinished(view, url);

View File

@ -152,11 +152,19 @@ public class IntentListView extends ListView {
ResolveInfo info = activityList.get(i);
ActivityInfo activity = info.activityInfo;
// fix bug in PackageManager - a replaced package name might cause non-exported intents to appear
if (activity.exported == false && !activity.packageName.equals(packageName)) {
activityList.remove(i);
i--;
continue;
}
// remove all IITCm intents, except for SendToClipboard in case Drive is not installed
if (activity.packageName.equals(packageName)) {
if (hasCopyIntent || !activity.name.equals(SendToClipboard.class.getCanonicalName())) {
activityList.remove(i);
i--;
continue;
}
}
}

View File

@ -1,8 +1,8 @@
// ==UserScript==
// @id overlay-kml@danielatkins
// @name IITC plugin: overlay KML
// @category Info
// @version 0.1.@@DATETIMEVERSION@@
// @category Layer
// @version 0.2.0.@@DATETIMEVERSION@@
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL @@UPDATEURL@@
// @downloadURL @@DOWNLOADURL@@

View File

@ -0,0 +1,174 @@
// ==UserScript==
// ==UserScript==
// @id iitc-plugin-bing-maps
// @name IITC plugin: Bing maps
// @category Map Tiles
// @version 0.1.0.@@DATETIMEVERSION@@
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL @@UPDATEURL@@
// @downloadURL @@DOWNLOADURL@@
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Add the maps.bing.com map layers (
// @include https://www.ingress.com/intel*
// @include http://www.ingress.com/intel*
// @match https://www.ingress.com/intel*
// @match http://www.ingress.com/intel*
// @grant none
// ==/UserScript==
@@PLUGINSTART@@
// PLUGIN START ////////////////////////////////////////////////////////
window.plugin.mapBing = function() {};
window.plugin.mapBing.setupBingLeaflet = function() {
//---------------------------------------------------------------------
// https://github.com/shramov/leaflet-plugins/blob/master/layer/tile/Bing.js
L.BingLayer = L.TileLayer.extend({
options: {
subdomains: [0, 1, 2, 3],
type: 'Aerial',
attribution: 'Bing',
culture: ''
},
initialize: function(key, options) {
L.Util.setOptions(this, options);
this._key = key;
this._url = null;
this.meta = {};
this.loadMetadata();
},
tile2quad: function(x, y, z) {
var quad = '';
for (var i = z; i > 0; i--) {
var digit = 0;
var mask = 1 << (i - 1);
if ((x & mask) != 0) digit += 1;
if ((y & mask) != 0) digit += 2;
quad = quad + digit;
}
return quad;
},
getTileUrl: function(p, z) {
var z = this._getZoomForUrl();
var subdomains = this.options.subdomains,
s = this.options.subdomains[Math.abs((p.x + p.y) % subdomains.length)];
return this._url.replace('{subdomain}', s)
.replace('{quadkey}', this.tile2quad(p.x, p.y, z))
.replace('{culture}', this.options.culture);
},
loadMetadata: function() {
// TODO? modify this to cache the metadata in - say - sessionStorage? localStorage?
var _this = this;
var cbid = '_bing_metadata_' + L.Util.stamp(this);
window[cbid] = function (meta) {
_this.meta = meta;
window[cbid] = undefined;
var e = document.getElementById(cbid);
e.parentNode.removeChild(e);
if (meta.errorDetails) {
alert("Got metadata" + meta.errorDetails);
return;
}
_this.initMetadata();
};
var url = "//dev.virtualearth.net/REST/v1/Imagery/Metadata/" + this.options.type + "?include=ImageryProviders&jsonp=" + cbid + "&key=" + this._key;
var script = document.createElement("script");
script.type = "text/javascript";
script.src = url;
script.id = cbid;
document.getElementsByTagName("head")[0].appendChild(script);
},
initMetadata: function() {
var r = this.meta.resourceSets[0].resources[0];
this.options.subdomains = r.imageUrlSubdomains;
this._url = r.imageUrl;
this._providers = [];
for (var i = 0; i < r.imageryProviders.length; i++) {
var p = r.imageryProviders[i];
for (var j = 0; j < p.coverageAreas.length; j++) {
var c = p.coverageAreas[j];
var coverage = {zoomMin: c.zoomMin, zoomMax: c.zoomMax, active: false};
var bounds = new L.LatLngBounds(
new L.LatLng(c.bbox[0]+0.01, c.bbox[1]+0.01),
new L.LatLng(c.bbox[2]-0.01, c.bbox[3]-0.01)
);
coverage.bounds = bounds;
coverage.attrib = p.attribution;
this._providers.push(coverage);
}
}
this._update();
},
_update: function() {
if (this._url == null || !this._map) return;
this._update_attribution();
L.TileLayer.prototype._update.apply(this, []);
},
_update_attribution: function() {
var bounds = this._map.getBounds();
var zoom = this._map.getZoom();
for (var i = 0; i < this._providers.length; i++) {
var p = this._providers[i];
if ((zoom <= p.zoomMax && zoom >= p.zoomMin) &&
bounds.intersects(p.bounds)) {
if (!p.active)
this._map.attributionControl.addAttribution(p.attrib);
p.active = true;
} else {
if (p.active)
this._map.attributionControl.removeAttribution(p.attrib);
p.active = false;
}
}
},
onRemove: function(map) {
for (var i = 0; i < this._providers.length; i++) {
var p = this._providers[i];
if (p.active) {
this._map.attributionControl.removeAttribution(p.attrib);
p.active = false;
}
}
L.TileLayer.prototype.onRemove.apply(this, [map]);
}
});
//---------------------------------------------------------------------
}
window.plugin.mapBing.setup = function() {
window.plugin.mapBing.setupBingLeaflet();
//set this to your API key
var bingApiKey = 'ArR2hTa2C9cRQZT-RmgrDkfvh3PwEVRl0gB34OO4wJI7vQNElg3DDWvbo5lfUs3p';
var bingTypes = {
'Road': "Road",
'Aerial': "Aerial",
'AerialWithLabels': "Aerial with labels",
};
for (type in bingTypes) {
var name = bingTypes[type];
var bingMap = new L.BingLayer(bingApiKey, {type: type, maxZoom:20});
layerChooser.addBaseLayer(bingMap, 'Bing '+name);
}
};
var setup = window.plugin.mapBing.setup;
// PLUGIN END //////////////////////////////////////////////////////////
@@PLUGINEND@@

View File

@ -0,0 +1,48 @@
// ==UserScript==
// @id iitc-plugin-nokia-ovi-maps
// @name IITC plugin: Nokia OVI maps
// @category Map Tiles
// @version 0.1.0.@@DATETIMEVERSION@@
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL @@UPDATEURL@@
// @downloadURL @@DOWNLOADURL@@
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Add various map layers from Nokia OVI Maps
// @include https://www.ingress.com/intel*
// @include http://www.ingress.com/intel*
// @match https://www.ingress.com/intel*
// @match http://www.ingress.com/intel*
// @grant none
// ==/UserScript==
@@PLUGINSTART@@
// PLUGIN START ////////////////////////////////////////////////////////
window.plugin.mapNokiaOvi = function() {};
window.plugin.mapNokiaOvi.setup = function() {
//the list of styles you'd like to see
var oviStyles = {
'normal.day': "Normal",
'normal.day.grey': "Normal (grey)",
'normal.day.transit': "Normal (transit)",
'satellite.day': "Satellite",
'terrain.day': "Terrain",
};
var oviOpt = {attribution: 'Imagery © Nokia OVI', maxZoom: 20};
$.each(oviStyles, function(key,value) {
oviOpt['style'] = key;
var oviMap = new L.TileLayer('http://maptile.maps.svc.ovi.com/maptiler/maptile/newest/{style}/{z}/{x}/{y}/256/png8', oviOpt);
layerChooser.addBaseLayer(oviMap, 'Nokia OVI '+value);
});
};
var setup = window.plugin.mapNokiaOvi.setup;
// PLUGIN END //////////////////////////////////////////////////////////
@@PLUGINEND@@

View File

@ -0,0 +1,56 @@
// ==UserScript==
// @id iitc-plugin-basemap-stamen@jonatkins
// @name IITC plugin: Map layers from stamen.com
// @category Map Tiles
// @version 0.1.0.@@DATETIMEVERSION@@
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL @@UPDATEURL@@
// @downloadURL @@DOWNLOADURL@@
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Adds the 'Toner' and 'Watercolor' map layers from maps.stamen.com
// @include https://www.ingress.com/intel*
// @include http://www.ingress.com/intel*
// @match https://www.ingress.com/intel*
// @match http://www.ingress.com/intel*
// @grant none
// ==/UserScript==
@@PLUGINSTART@@
// PLUGIN START ////////////////////////////////////////////////////////
// use own namespace for plugin
window.plugin.mapTileStamen = function() {};
window.plugin.mapTileStamen.setup = function() {
load('http://maps.stamen.com/js/tile.stamen.js?v1.2.3').thenRun(window.plugin.mapTileStamen.addLayer);
}
window.plugin.mapTileStamen.addLayer = function() {
var types = {
'toner': 'Toner',
// 'toner-hybrid': 'Toner Hybrid', // transparent layer. could be usefun over satelliate imagery or similar
// 'toner-labels': 'Toner Labels', // transparent layer. could be usefun over satelliate imagery or similar
// 'toner-lines': 'Toner Lines', // transparent layer. could be usefun over satelliate imagery or similar
'toner-background': 'Toner Background',
'toner-lite': 'Toner Lite',
'watercolor': 'Watercolor',
};
for (var type in types) {
var name = types[type];
var layer = new L.StamenTileLayer(type);
layerChooser.addBaseLayer(layer,'Stamen '+name);
}
};
var setup = window.plugin.mapTileStamen.setup;
// PLUGIN END //////////////////////////////////////////////////////////
@@PLUGINEND@@

View File

@ -2,7 +2,7 @@
// @id iitc-plugin-player-tracker@breunigs
// @name IITC Plugin: Player tracker
// @category Layer
// @version 0.9.6.@@DATETIMEVERSION@@
// @version 0.10.0.@@DATETIMEVERSION@@
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL @@UPDATEURL@@
// @downloadURL @@DOWNLOADURL@@
@ -62,12 +62,20 @@ window.plugin.playerTracker.setup = function() {
});
}
});
plugin.playerTracker.oms = new OverlappingMarkerSpiderfier(map);
plugin.playerTracker.oms = new OverlappingMarkerSpiderfier(map, {keepSpiderfied: true, legWeight: 3.5});
plugin.playerTracker.oms.legColors = {'usual': '#FFFF00', 'highlighted': '#FF0000'};
plugin.playerTracker.oms.legWeight = 3.5;
var playerPopup = new L.Popup({offset: L.point([0,-20])});
plugin.playerTracker.oms.addListener('click', function(player) {
window.renderPortalDetails(player.options.referenceToPortal);
playerPopup.setContent(player.options.desc);
playerPopup.setLatLng(player.getLatLng());
map.openPopup(playerPopup)
});
plugin.playerTracker.oms.addListener('spiderfy', function(markers) {
map.closePopup();
});
addHook('publicChatDataAvailable', window.plugin.playerTracker.handleData);
@ -226,6 +234,7 @@ window.plugin.playerTracker.processNewData = function(data) {
}
window.plugin.playerTracker.getLatLngFromEvent = function(ev) {
//TODO? add weight to certain events, or otherwise prefer them, to give better locations?
var lats = 0;
var lngs = 0;
$.each(ev.latlngs, function() {
@ -275,7 +284,7 @@ window.plugin.playerTracker.drawData = function() {
polyLineByAgeEnl[ageBucket].push(line);
}
// tooltip for marker
// popup for marker
var evtsLength = playerData.events.length;
var last = playerData.events[evtsLength-1];
var ago = plugin.playerTracker.ago;
@ -295,17 +304,22 @@ window.plugin.playerTracker.drawData = function() {
}
}
title += '\n'
+ ago(last.time, now) + ' ago\n'
title += '<br>'
+ ago(last.time, now) + ' ago<br>'
+ window.chat.getChatPortalName(last);
// show previous data in tooltip
var minsAgo = '\t<span style="white-space: nowrap;"> ago</span>\t';
if(evtsLength >= 2)
title += '\n&nbsp;\nprevious locations:\n';
if(evtsLength >= 2) {
title += '<br>&nbsp;<br>previous locations:<br>'
+ '<table style="border-spacing:0">';
}
for(var i = evtsLength - 2; i >= 0 && i >= evtsLength - 10; i--) {
var ev = playerData.events[i];
title += ago(ev.time, now) + minsAgo + window.chat.getChatPortalName(ev) + '\n';
title += '<tr align="left"><td>' + ago(ev.time, now) + '</td>'
+ '<td>ago</td>'
+ '<td>' + window.chat.getChatPortalName(ev) + '</td></tr>';
}
if(evtsLength >= 2)
title += '</table>';
// calculate the closest portal to the player
var eventPortal = []
@ -329,13 +343,13 @@ window.plugin.playerTracker.drawData = function() {
// marker itself
var icon = playerData.team === 'RESISTANCE' ? new plugin.playerTracker.iconRes() : new plugin.playerTracker.iconEnl();
var m = L.marker(gllfe(last), {title: title, icon: icon, referenceToPortal: closestPortal, opacity: absOpacity});
// ensure tooltips are closed, sometimes they linger
m.on('mouseout', function() { $(this._icon).tooltip('close'); });
// as per OverlappingMarkerSpiderfier docs, click events (popups, etc) must be handled via it rather than the standard
// marker click events. so store the popup text in the options, then display it in the oms click handler
var m = L.marker(gllfe(last), {icon: icon, referenceToPortal: closestPortal, opacity: absOpacity, desc: title});
// m.bindPopup(title);
m.addTo(playerData.team === 'RESISTANCE' ? plugin.playerTracker.drawnTracesRes : plugin.playerTracker.drawnTracesEnl);
plugin.playerTracker.oms.addMarker(m);
// jQueryUI doesnt automatically notice the new markers
window.setupTooltips($(m._icon));
});
// draw the poly lines to the map
@ -372,13 +386,6 @@ window.plugin.playerTracker.handleData = function(data) {
plugin.playerTracker.discardOldData();
plugin.playerTracker.processNewData(data);
// remove old popups
plugin.playerTracker.drawnTracesEnl.eachLayer(function(layer) {
if(layer._icon) $(layer._icon).tooltip('destroy');
});
plugin.playerTracker.drawnTracesRes.eachLayer(function(layer) {
if(layer._icon) $(layer._icon).tooltip('destroy');
});
plugin.playerTracker.oms.clearMarkers();
plugin.playerTracker.drawnTracesEnl.clearLayers();
plugin.playerTracker.drawnTracesRes.clearLayers();

View File

@ -2,7 +2,7 @@
// @id iitc-plugin-portals-list@teo96
// @name IITC plugin: show list of portals
// @category Info
// @version 0.0.17.@@DATETIMEVERSION@@
// @version 0.0.18.@@DATETIMEVERSION@@
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL @@UPDATEURL@@
// @downloadURL @@DOWNLOADURL@@
@ -212,10 +212,13 @@ window.plugin.portalslist.displayPL = function() {
$('#portalslist').html(window.plugin.portalslist.portalTable($(this).data('sort'),window.plugin.portalslist.sortOrder,2));
});
//run the name resolving process
resolvePlayerNames();
//debug tools
//end = new Date().getTime();
//console.log('***** end : ' + end + ' and Elapse : ' + (end - start));
}
}
window.plugin.portalslist.portalTable = function(sortBy, sortOrder, filter) {
// sortOrder <0 ==> desc, >0 ==> asc, i use sortOrder * -1 to change the state

View File

@ -2,7 +2,7 @@
// @id iitc-plugin-scoreboard@vita10gy
// @name IITC plugin: show a localized scoreboard.
// @category Info
// @version 0.1.8.@@DATETIMEVERSION@@
// @version 0.1.9.@@DATETIMEVERSION@@
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL @@UPDATEURL@@
// @downloadURL @@DOWNLOADURL@@
@ -291,6 +291,9 @@ window.plugin.scoreboard.display = function() {
$(document).on('click', '#players table th', function() {
$('#players').html(window.plugin.scoreboard.playerTable($(this).data('sort')));
});
//run the name resolving process
resolvePlayerNames();
}
window.plugin.scoreboard.portalDistance = function(portalAE6Location, portalBE6Location) {

View File

@ -982,3 +982,53 @@ td + td {
display: none;
}
/* leaflet popups - restyle to match the theme of IITC */
#map .leaflet-popup {
pointer-events: none;
}
#map .leaflet-popup-content-wrapper {
border-radius: 0px;
-webkit-border-radius: 0px;
border: 1px solid #20A8B1;
background: #0e3d4e;
pointer-events: auto;
}
#map .leaflet-popup-content {
color: #ffce00;
margin: 5px 8px;
}
#map .leaflet-popup-close-button {
padding: 2px 1px 0 0;
font-size: 12px;
line-height: 8px;
width: 10px;
height: 10px;
pointer-events: auto;
}
#map .leaflet-popup-tip {
/* change the tip from an arrow to a simple line */
background: #20A8B1;
width: 1px;
height: 20px;
padding: 0;
margin: 0 0 0 20px;
-webkit-transform: none;
-moz-transform: none;
-ms-transform: none;
-o-transform: none;
transform: none;
}
/* misc */
.no-pointer-events {
pointer-events: none;
}

View File

@ -13,6 +13,12 @@ offers many more features. It is available for
<h3>Latest news</h3>
<h4>6th November 2013</h4>
<p>
IITC 0.14.5 and IITC Mobile 0.7.7.1 have been released. This contains a fix to work with the latest intel site updates.
Other than this, it is identical to the 0.14.4/0.7.7 release.
</p>
<h4>29th October 2013</h4>
<p>
IITC 0.14.4 and IITC Mobile 0.7.7 have just been released. A critical update required to work with changes made to the

View File

@ -1,5 +1,11 @@
<h2>News</h2>
<h4>6th November 2013</h4>
<p>
IITC 0.14.5 and IITC Mobile 0.7.7.1 have been released. This contains a fix to work with the latest intel site updates.
Other than this, it is identical to the 0.14.4/0.7.7 release.
</p>
<h4>29th October 2013</h4>
<p>
IITC 0.14.4 and IITC Mobile 0.7.7 have just been released. A critical update required to work with changes made to the