Merge branch 'to-push' of github.com:nexushoratio/ingress-intel-total-conversion into to-push
Conflicts: plugins/portal-defense.user.js plugins/show-linked-portals.user.js
This commit is contained in:
@ -171,7 +171,7 @@ window.artifact.updateLayer = function() {
|
||||
artifact._layer.clearLayers();
|
||||
|
||||
$.each(artifact.portalInfo, function(guid,data) {
|
||||
var latlng = L.latLng ([data._entityData.locationE6.latE6/1E6, data._entityData.locationE6.lngE6/1E6]);
|
||||
var latlng = L.latLng ([data._entityData.latE6/1E6, data._entityData.lngE6/1E6]);
|
||||
|
||||
// jarvis shard icon
|
||||
var iconUrl = undefined;
|
||||
@ -235,8 +235,8 @@ window.artifact.showArtifactList = function() {
|
||||
|
||||
var sortVal = 0;
|
||||
|
||||
var onclick = 'zoomToAndShowPortal(\''+guid+'\',['+data._entityData.locationE6.latE6/1E6+','+data._entityData.locationE6.lngE6/1E6+'])';
|
||||
var row = '<tr><td class="portal"><a onclick="'+onclick+'" title="'+escapeHtmlSpecialChars(data._entityData.portalV2.descriptiveText.ADDRESS||'')+'">'+escapeHtmlSpecialChars(data._entityData.portalV2.descriptiveText.TITLE)+'</a></td>';
|
||||
var onclick = 'zoomToAndShowPortal(\''+guid+'\',['+data._entityData.latE6/1E6+','+data._entityData.lngE6/1E6+'])';
|
||||
var row = '<tr><td class="portal"><a onclick="'+onclick+'">'+escapeHtmlSpecialChars(data._entityData.title)+'</a></td>';
|
||||
|
||||
row += '<td class="info">';
|
||||
|
||||
|
@ -338,7 +338,6 @@ window.setMapBaseLayer = function() {
|
||||
// included as inline script in the original site, the data is static
|
||||
// and cannot be updated.
|
||||
window.setupPlayerStat = function() {
|
||||
PLAYER.guid = playerNameToGuid(PLAYER.nickname);
|
||||
var level;
|
||||
var ap = parseInt(PLAYER.ap);
|
||||
for(level = 0; level < MIN_AP_FOR_LEVEL.length; level++) {
|
||||
@ -531,7 +530,6 @@ function boot() {
|
||||
window.setupTaphold();
|
||||
window.setupStyles();
|
||||
window.setupDialogs();
|
||||
window.setupPlayerNameCache();
|
||||
window.setupMap();
|
||||
window.setupGeosearch();
|
||||
window.setupRedeem();
|
||||
@ -542,6 +540,7 @@ function boot() {
|
||||
window.setupPlayerStat();
|
||||
window.setupTooltips();
|
||||
window.chat.setup();
|
||||
window.portalDetail.setup();
|
||||
window.setupQRLoadLib();
|
||||
window.setupLayerChooserSelectOne();
|
||||
window.setupLayerChooserStatusRecorder();
|
||||
|
14
code/chat.js
14
code/chat.js
@ -127,7 +127,7 @@ window.chat.requestFaction = function(getOlderMsgs, isRetry) {
|
||||
|
||||
var d = chat.genPostData(true, chat._faction, getOlderMsgs);
|
||||
var r = window.postAjax(
|
||||
'getPaginatedPlextsV2',
|
||||
'getPaginatedPlexts',
|
||||
d,
|
||||
function(data, textStatus, jqXHR) { chat.handleFaction(data, getOlderMsgs); },
|
||||
isRetry
|
||||
@ -178,7 +178,7 @@ window.chat.requestPublic = function(getOlderMsgs, isRetry) {
|
||||
|
||||
var d = chat.genPostData(false, chat._public, getOlderMsgs);
|
||||
var r = window.postAjax(
|
||||
'getPaginatedPlextsV2',
|
||||
'getPaginatedPlexts',
|
||||
d,
|
||||
function(data, textStatus, jqXHR) { chat.handlePublic(data, getOlderMsgs); },
|
||||
isRetry
|
||||
@ -284,11 +284,9 @@ window.chat.writeDataToHash = function(newData, storageHash, isPublicChannel, is
|
||||
switch(markup[0]) {
|
||||
case 'SENDER': // user generated messages
|
||||
nick = markup[1].plain.slice(0, -2); // cut “: ” at end
|
||||
pguid = markup[1].guid;
|
||||
break;
|
||||
|
||||
case 'PLAYER': // automatically generated messages
|
||||
pguid = markup[1].guid;
|
||||
nick = markup[1].plain;
|
||||
team = markup[1].team === 'RESISTANCE' ? TEAM_RES : TEAM_ENL;
|
||||
if(ind > 0) msg += nick; // don’t repeat nick directly
|
||||
@ -351,13 +349,9 @@ window.chat.writeDataToHash = function(newData, storageHash, isPublicChannel, is
|
||||
if ((!isPublicChannel) && (!isSecureMessage)) msg = '<span style="color: #ff6">[public]</span> ' + msg;
|
||||
|
||||
|
||||
// format: timestamp, autogenerated, HTML message, player guid
|
||||
storageHash.data[json[0]] = [json[1], auto, chat.renderMsg(msg, nick, time, team, msgToPlayer, systemNarrowcast), pguid];
|
||||
// format: timestamp, autogenerated, HTML message
|
||||
storageHash.data[json[0]] = [json[1], auto, chat.renderMsg(msg, nick, time, team, msgToPlayer, systemNarrowcast)];
|
||||
|
||||
// if we're processing older messages, we could be looking at pre-name change mentions or similar
|
||||
// so in that case, flag it so we don't overwrite existing name cache entries.
|
||||
// (it's not perfect - the initial request has the wrong value here)
|
||||
window.setPlayerName(pguid, nick, isOlderMsgs); // free nick name resolves.
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,14 @@
|
||||
// given the entity detail data, returns the team the entity belongs
|
||||
// to. Uses TEAM_* enum values.
|
||||
window.getTeam = function(details) {
|
||||
return teamStringToId(details.controllingTeam.team);
|
||||
}
|
||||
|
||||
window.teamStringToId = function(teamStr) {
|
||||
var team = TEAM_NONE;
|
||||
if(details.controllingTeam.team === 'ALIENS' || details.controllingTeam.team === 'ENLIGHTENED') team = TEAM_ENL;
|
||||
if(details.controllingTeam.team === 'RESISTANCE') team = TEAM_RES;
|
||||
if(teamStr === 'ENLIGHTENED') team = TEAM_ENL;
|
||||
if(teamStr === 'RESISTANCE') team = TEAM_RES;
|
||||
return team;
|
||||
}
|
||||
|
||||
|
||||
|
@ -48,7 +48,8 @@
|
||||
// called after each map data request finished. Argument is
|
||||
// {success: boolean} indicated the request success or fail.
|
||||
// iitcLoaded: called after IITC and all plugins loaded
|
||||
|
||||
// portalDetailLoaded: called when a request to load full portal detail
|
||||
// completes. guid, success, details parameters
|
||||
|
||||
window._hooks = {}
|
||||
window.VALID_HOOKS = [
|
||||
@ -58,7 +59,8 @@ window.VALID_HOOKS = [
|
||||
'portalDetailsUpdated',
|
||||
'publicChatDataAvailable', 'factionChatDataAvailable',
|
||||
'requestFinished', 'nicknameClicked',
|
||||
'geoSearch', 'iitcLoaded'];
|
||||
'geoSearch', 'iitcLoaded',
|
||||
'portalDetailLoaded'];
|
||||
|
||||
window.runHooks = function(event, data) {
|
||||
if(VALID_HOOKS.indexOf(event) === -1) throw('Unknown event type: ' + event);
|
||||
|
@ -104,7 +104,6 @@ window.Render.prototype.processDeletedGameEntityGuids = function(deleted) {
|
||||
}
|
||||
|
||||
window.Render.prototype.processGameEntities = function(entities) {
|
||||
var portalGuids = [];
|
||||
|
||||
for (var i in entities) {
|
||||
var ent = entities[i];
|
||||
@ -112,14 +111,9 @@ window.Render.prototype.processGameEntities = function(entities) {
|
||||
// don't create entities in the 'deleted' list
|
||||
if (!(ent[0] in this.deletedGuid)) {
|
||||
this.createEntity(ent);
|
||||
if ('portalV2' in ent[2]) portalGuids.push(ent[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// now reconstruct links 'optimised' out of the data from the portal link data
|
||||
for (var i in portalGuids) {
|
||||
this.createLinksFromPortalData(portalGuids[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -130,6 +124,7 @@ window.Render.prototype.endRenderPass = function() {
|
||||
// check to see if there are any entities we haven't seen. if so, delete them
|
||||
for (var guid in window.portals) {
|
||||
// special case for selected portal - it's kept even if not seen
|
||||
// artifact (e.g. jarvis shard) portals are also kept - but they're always 'seen'
|
||||
if (!(guid in this.seenPortalsGuid) && guid !== selectedPortal) {
|
||||
this.deletePortalEntity(guid);
|
||||
}
|
||||
@ -214,22 +209,6 @@ window.Render.prototype.deleteFieldEntity = function(guid) {
|
||||
var f = window.fields[guid];
|
||||
var fd = f.options.details;
|
||||
|
||||
var deletePortalLinkedField = function(pguid) {
|
||||
if (pguid in window.portals) {
|
||||
var pd = window.portals[pguid].options.details;
|
||||
if (pd.portalV2.linkedFields) {
|
||||
var i = pd.portalV2.linkedFields.indexOf(guid);
|
||||
if (i >= 0) {
|
||||
pd.portalV2.linkedFields.splice(i,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deletePortalLinkedField (fd.capturedRegion.vertexA.guid);
|
||||
deletePortalLinkedField (fd.capturedRegion.vertexB.guid);
|
||||
deletePortalLinkedField (fd.capturedRegion.vertexC.guid);
|
||||
|
||||
fieldsFactionLayers[f.options.team].removeLayer(f);
|
||||
delete window.fields[guid];
|
||||
}
|
||||
@ -244,23 +223,30 @@ window.Render.prototype.createEntity = function(ent) {
|
||||
|
||||
|
||||
// logic on detecting entity type based on the stock site javascript.
|
||||
if ("portalV2" in ent[2]) {
|
||||
this.createPortalEntity(ent);
|
||||
} else if ("capturedRegion" in ent[2]) {
|
||||
this.createFieldEntity(ent);
|
||||
} else if ("edge" in ent[2]) {
|
||||
this.createLinkEntity(ent);
|
||||
} else {
|
||||
console.warn("Unknown entity found: "+JSON.stringify(ent));
|
||||
}
|
||||
switch (ent[2].type) {
|
||||
case 'portal':
|
||||
this.createPortalEntity(ent);
|
||||
break;
|
||||
|
||||
case 'edge':
|
||||
this.createLinkEntity(ent);
|
||||
break;
|
||||
|
||||
case 'region':
|
||||
this.createFieldEntity(ent);
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn('unknown entity found: '+JSON.stringify(ent));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
window.Render.prototype.createPortalEntity = function(ent) {
|
||||
this.seenPortalsGuid[ent[0]] = true; // flag we've seen it
|
||||
|
||||
var previousDetails = undefined;
|
||||
var previousData = undefined;
|
||||
|
||||
// check if entity already exists
|
||||
if (ent[0] in window.portals) {
|
||||
@ -275,21 +261,17 @@ window.Render.prototype.createPortalEntity = function(ent) {
|
||||
|
||||
// remember the old details, for the callback
|
||||
|
||||
previousDetails = p.options.details;
|
||||
previousData = p.options.data;
|
||||
|
||||
this.deletePortalEntity(ent[0]);
|
||||
}
|
||||
|
||||
var portalLevel = getPortalLevel(ent[2]);
|
||||
var team = getTeam(ent[2]);
|
||||
var portalLevel = parseInt(ent[2].level);
|
||||
var team = teamStringToId(ent[2].team);
|
||||
// the data returns unclaimed portals as level 1 - but IITC wants them treated as level 0
|
||||
if (team == TEAM_NONE) portalLevel = 0;
|
||||
|
||||
var latlng = L.latLng(ent[2].locationE6.latE6/1E6, ent[2].locationE6.lngE6/1E6);
|
||||
|
||||
//TODO: move marker creation, style setting, etc into a separate class
|
||||
//(as it's called from elsewhere - e.g. selecting/deselecting portals)
|
||||
|
||||
//ALSO: change API for highlighters - make them return the updated style rather than directly calling setStyle on the portal marker
|
||||
//(can this be done in a backwardly-compatible way??)
|
||||
var latlng = L.latLng(ent[2].latE6/1E6, ent[2].lngE6/1E6);
|
||||
|
||||
var dataOptions = {
|
||||
level: portalLevel,
|
||||
@ -297,32 +279,16 @@ window.Render.prototype.createPortalEntity = function(ent) {
|
||||
ent: ent, // LEGACY - TO BE REMOVED AT SOME POINT! use .guid, .timestamp and .details instead
|
||||
guid: ent[0],
|
||||
timestamp: ent[1],
|
||||
details: ent[2]
|
||||
data: ent[2]
|
||||
};
|
||||
|
||||
// Javascript uses references for objects. For now, at least, we need to modify the data within
|
||||
// the options.details.portalV2 (to add in linkedFields). To avoid tainting the original data (which may be cached)
|
||||
// we'll shallow-copy these items
|
||||
dataOptions.details = $.extend({}, dataOptions.details);
|
||||
dataOptions.details.portalV2 = $.extend({}, dataOptions.details.portalV2);
|
||||
|
||||
|
||||
// create a linkedFields entry and add it to details - various bits of code assumes it will exist
|
||||
for (var fguid in window.fields) {
|
||||
var fd = window.fields[fguid].options.details;
|
||||
if ( fd.capturedRegion.vertexA.guid == ent[0] || fd.capturedRegion.vertexB.guid == ent[0] || fd.capturedRegion.vertexC.guid == ent[0]) {
|
||||
if (!dataOptions.details.portalV2.linkedFields) dataOptions.details.portalV2.linkedFields = [];
|
||||
dataOptions.details.portalV2.linkedFields.push(fguid);
|
||||
}
|
||||
}
|
||||
|
||||
var marker = createMarker(latlng, dataOptions);
|
||||
|
||||
marker.on('click', function() { window.renderPortalDetails(ent[0]); });
|
||||
marker.on('dblclick', function() { window.renderPortalDetails(ent[0]); window.map.setView(latlng, 17); });
|
||||
|
||||
|
||||
window.runHooks('portalAdded', {portal: marker, previousDetails: previousDetails});
|
||||
window.runHooks('portalAdded', {portal: marker, previousData: previousData});
|
||||
|
||||
window.portals[ent[0]] = marker;
|
||||
|
||||
@ -370,12 +336,11 @@ window.Render.prototype.createFieldEntity = function(ent) {
|
||||
this.deleteFieldEntity(ent[0]); // option 2, for now
|
||||
}
|
||||
|
||||
var team = getTeam(ent[2]);
|
||||
var reg = ent[2].capturedRegion;
|
||||
var team = teamStringToId(ent[2].team);
|
||||
var latlngs = [
|
||||
L.latLng(reg.vertexA.location.latE6/1E6, reg.vertexA.location.lngE6/1E6),
|
||||
L.latLng(reg.vertexB.location.latE6/1E6, reg.vertexB.location.lngE6/1E6),
|
||||
L.latLng(reg.vertexC.location.latE6/1E6, reg.vertexC.location.lngE6/1E6)
|
||||
L.latLng(ent[2].points[0].latE6/1E6, ent[2].points[0].lngE6/1E6),
|
||||
L.latLng(ent[2].points[1].latE6/1E6, ent[2].points[1].lngE6/1E6),
|
||||
L.latLng(ent[2].points[2].latE6/1E6, ent[2].points[2].lngE6/1E6)
|
||||
];
|
||||
|
||||
var poly = L.geodesicPolygon(latlngs, {
|
||||
@ -387,27 +352,9 @@ window.Render.prototype.createFieldEntity = function(ent) {
|
||||
team: team,
|
||||
guid: ent[0],
|
||||
timestamp: ent[1],
|
||||
details: ent[2],
|
||||
// LEGACY FIELDS: these duplicate data available via .details, as IITC previously stored it in data and vertices
|
||||
data: ent[2],
|
||||
vertices: ent[2].capturedRegion
|
||||
});
|
||||
|
||||
|
||||
// now fill in any references portals linkedFields data
|
||||
var addPortalLinkedField = function(pguid) {
|
||||
if (pguid in window.portals) {
|
||||
var pd = window.portals[pguid].options.details;
|
||||
if (!pd.portalV2.linkedFields) pd.portalV2.linkedFields = [];
|
||||
if (pd.portalV2.linkedFields.indexOf(pguid) <0 ) {
|
||||
pd.portalV2.linkedFields.push (ent[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
addPortalLinkedField(ent[2].capturedRegion.vertexA.guid);
|
||||
addPortalLinkedField(ent[2].capturedRegion.vertexB.guid);
|
||||
addPortalLinkedField(ent[2].capturedRegion.vertexC.guid);
|
||||
|
||||
runHooks('fieldAdded',{field: poly});
|
||||
|
||||
window.fields[ent[0]] = poly;
|
||||
@ -433,11 +380,10 @@ window.Render.prototype.createLinkEntity = function(ent,faked) {
|
||||
this.deleteLinkEntity(ent[0]); // option 2 - for now
|
||||
}
|
||||
|
||||
var team = getTeam(ent[2]);
|
||||
var edge = ent[2].edge;
|
||||
var team = teamStringToId(ent[2].team);
|
||||
var latlngs = [
|
||||
L.latLng(edge.originPortalLocation.latE6/1E6, edge.originPortalLocation.lngE6/1E6),
|
||||
L.latLng(edge.destinationPortalLocation.latE6/1E6, edge.destinationPortalLocation.lngE6/1E6)
|
||||
L.latLng(ent[2].oLatE6/1E6, ent[2].oLngE6/1E6),
|
||||
L.latLng(ent[2].dLatE6/1E6, ent[2].dLngE6/1E6)
|
||||
];
|
||||
var poly = L.geodesicPolyline(latlngs, {
|
||||
color: COLORS[team],
|
||||
@ -448,8 +394,6 @@ window.Render.prototype.createLinkEntity = function(ent,faked) {
|
||||
team: team,
|
||||
guid: ent[0],
|
||||
timestamp: ent[1],
|
||||
details: ent[2],
|
||||
// LEGACY FIELDS: these duplicate data available via .details, as IITC previously stored it in data and vertices
|
||||
data: ent[2]
|
||||
});
|
||||
|
||||
@ -465,56 +409,6 @@ window.Render.prototype.createLinkEntity = function(ent,faked) {
|
||||
}
|
||||
|
||||
|
||||
window.Render.prototype.createLinksFromPortalData = function(portalGuid) {
|
||||
|
||||
var sourcePortal = portals[portalGuid];
|
||||
|
||||
for (var sourceLinkIndex in sourcePortal.options.details.portalV2.linkedEdges||[]) {
|
||||
var sourcePortalLinkInfo = sourcePortal.options.details.portalV2.linkedEdges[sourceLinkIndex];
|
||||
|
||||
// portals often contain details for edges that don't exist. so only consider faking an edge if this
|
||||
// is the origin portal
|
||||
if (sourcePortalLinkInfo.isOrigin) {
|
||||
|
||||
// ... and the other porta has matching link information.
|
||||
if (sourcePortalLinkInfo.otherPortalGuid in portals) {
|
||||
|
||||
var targetPortal = portals[sourcePortalLinkInfo.otherPortalGuid];
|
||||
|
||||
for (var targetLinkIndex in targetPortal.options.details.portalV2.linkedEdges||[]) {
|
||||
var targetPortalLinkInfo = targetPortal.options.details.portalV2.linkedEdges[targetLinkIndex];
|
||||
|
||||
if (targetPortalLinkInfo.edgeGuid == sourcePortalLinkInfo.edgeGuid) {
|
||||
// yes - edge in both portals. create it
|
||||
|
||||
var fakeEnt = [
|
||||
sourcePortalLinkInfo.edgeGuid,
|
||||
0, // mtime for entity data - unknown when faking it, so zero will be the oldest possible
|
||||
{
|
||||
controllingTeam: sourcePortal.options.details.controllingTeam,
|
||||
edge: {
|
||||
originPortalGuid: portalGuid,
|
||||
originPortalLocation: sourcePortal.options.details.locationE6,
|
||||
destinationPortalGuid: sourcePortalLinkInfo.otherPortalGuid,
|
||||
destinationPortalLocation: targetPortal.options.details.locationE6
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
this.createLinkEntity(fakeEnt,true);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
window.Render.prototype.updateEntityVisibility = function() {
|
||||
if (this.entityVisibilityZoom === undefined || this.entityVisibilityZoom != map.getZoom()) {
|
||||
|
@ -28,7 +28,7 @@ window.MapDataRequest = function() {
|
||||
this.MIN_TILES_PER_REQUEST = 4;
|
||||
|
||||
// number of times to retry a tile after a 'bad' error (i.e. not a timeout)
|
||||
this.MAX_TILE_RETRIES = 3;
|
||||
this.MAX_TILE_RETRIES = 1;
|
||||
|
||||
// refresh timers
|
||||
this.MOVE_REFRESH = 1; //time, after a map move (pan/zoom) before starting the refresh processing
|
||||
@ -45,7 +45,7 @@ window.MapDataRequest = function() {
|
||||
this.RUN_QUEUE_DELAY = 0.5;
|
||||
|
||||
// delay before requeuing tiles in failed requests
|
||||
this.BAD_REQUEST_REQUEUE_DELAY = 5; // longer delay before retrying a completely failed request - as in this case the servers are struggling
|
||||
this.BAD_REQUEST_REQUEUE_DELAY = 10; // longer delay before retrying a completely failed request - as in this case the servers are struggling
|
||||
|
||||
// a delay before processing the queue after requeuing tiles. this gives a chance for other requests to finish
|
||||
// or other requeue actions to happen before the queue is processed, allowing better grouping of requests
|
||||
@ -391,7 +391,7 @@ window.MapDataRequest.prototype.sendTileRequest = function(tiles) {
|
||||
var savedThis = this;
|
||||
|
||||
// NOTE: don't add the request with window.request.add, as we don't want the abort handling to apply to map data any more
|
||||
window.postAjax('getThinnedEntitiesV4', data,
|
||||
window.postAjax('getThinnedEntities', data,
|
||||
function(data, textStatus, jqXHR) { savedThis.handleResponse (data, tiles, true); }, // request successful callback
|
||||
function() { savedThis.handleResponse (undefined, tiles, false); } // request failed callback
|
||||
);
|
||||
|
223
code/munge.js
223
code/munge.js
@ -14,140 +14,52 @@
|
||||
var requestParameterMunges = [
|
||||
// obsolete munge sets (they don't have some of the new parameters) deleted
|
||||
|
||||
// set 7 - 2013-11-06
|
||||
// set 10 - 2013-11-27
|
||||
{
|
||||
'dashboard.getArtifactInfo': 'artifacts', // GET_ARTIFACT_INFO: new (and not obfuscated?!)
|
||||
'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
|
||||
'dashboard.getArtifactInfo': 'artifacts', // GET_ARTIFACT_INFO
|
||||
'dashboard.getGameScore': '4oid643d9zc168hs', // GET_GAME_SCORE
|
||||
'dashboard.getPaginatedPlexts': 's1msyywq51ntudpe', // GET_PAGINATED_PLEXTS
|
||||
'dashboard.getThinnedEntities': '4467ff9bgxxe4csa', // GET_THINNED_ENTITIES
|
||||
'dashboard.getPortalDetails': 'c00thnhf1yp3z6mn', // GET_PORTAL_DETAILS
|
||||
'dashboard.redeemReward': '66l9ivg39ygfqqjm', // REDEEM_REWARD
|
||||
'dashboard.sendInviteEmail': 'cgb7hi5hglv0xx8k', // SEND_INVITE_EMAIL
|
||||
'dashboard.sendPlext': 'etn9xq7brd6947kq', // 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
|
||||
method: 'yyngyttbmmbuvdpa',
|
||||
version: 'avz401t36lzrapis',
|
||||
version_parameter: 'c5d0a5d608f729a1232bebdc12fb86ba5fb6c43f',
|
||||
|
||||
// GET_THINNED_ENTITIES
|
||||
quadKeys: 'iqy8e2d3zpne0cmh', //guessed parameter name - only seen munged
|
||||
quadKeys: '1mpmxz2yun22rwnn',
|
||||
|
||||
// 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',
|
||||
desiredNumItems: 'nzd23jqm9k1cnnij',
|
||||
minLatE6: '0dod6onpa1s4fezp',
|
||||
minLngE6: 'soass3t7mm7anneo',
|
||||
maxLatE6: 'cvarmr3o00ngylo1',
|
||||
maxLngE6: 'udzwnlx07hzd3bfo',
|
||||
minTimestampMs: '9iiiks138gkf8xho',
|
||||
maxTimestampMs: '94wm0u3sc3sgzq7x',
|
||||
chatTab: 'tqfj4a3okzn5v5o1',
|
||||
ascendingTimestampOrder: '5jv1m90sq35u6utq',
|
||||
|
||||
// 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',
|
||||
},
|
||||
|
||||
// set 8 - 2013-11-07
|
||||
{
|
||||
'dashboard.getArtifactInfo': 'artifacts', // GET_ARTIFACT_INFO: new (and not obfuscated?!)
|
||||
'dashboard.getGameScore': 'lls4clhel87apzpa', // GET_GAME_SCORE
|
||||
'dashboard.getPaginatedPlextsV2': 'r6n2xgcd8wjsm4og', // GET_PAGINATED_PLEXTS
|
||||
'dashboard.getThinnedEntitiesV4': '1ybigzcf2sifu34b', // GET_THINNED_ENTITIES
|
||||
'dashboard.getPlayersByGuids': 'uig0xeb6trclqd2l', // LOOKUP_PLAYERS
|
||||
'dashboard.redeemReward': '7dd7x64cc2lbutoq', // REDEEM_REWARD
|
||||
'dashboard.sendInviteEmail': 'd8p6dvwilsr460u3', // SEND_INVITE_EMAIL
|
||||
'dashboard.sendPlext': 'repg2orpg7htkoto', // SEND_PLEXT
|
||||
|
||||
// common parameters
|
||||
method: '97aes4vnlvyhoxik',
|
||||
version: 'an8mglz21qabq3wq', //guessed parameter name - only seen munged
|
||||
version_parameter: 'b92c9d055fcdf715887b173c706e7a2c267e32c5', // passed as the value to the above parameter
|
||||
|
||||
// GET_THINNED_ENTITIES
|
||||
quadKeys: 'mhjknavysslwfhk6', //guessed parameter name - only seen munged
|
||||
|
||||
// GET_PAGINATED_PLEXTS
|
||||
desiredNumItems: 'l61g8u397alq3j1x',
|
||||
minLatE6: 'wwsvpboc5bxd1s9q',
|
||||
minLngE6: '48l4x7ngfsz47z3u',
|
||||
maxLatE6: 'p3m1qg81uqldizu6',
|
||||
maxLngE6: 'h4kv1eef878vfyk3',
|
||||
minTimestampMs: 'uj1vcy9ufws24v2c',
|
||||
maxTimestampMs: '8pt1x5nd9hk5vakv',
|
||||
chatTab: 'zy1yc1rfczashshu', //guessed parameter name - only seen munged
|
||||
ascendingTimestampOrder: 'duyuskmky68nl2ci',
|
||||
|
||||
// SEND_PLEXT
|
||||
message: 'xktwjguq0nohzioa',
|
||||
latE6: 'm4crflfaibmg9mdf',
|
||||
lngE6: 'h6jfungrw5ii830r',
|
||||
// chatTab: 'zy1yc1rfczashshu', //guessed parameter name - only seen munged
|
||||
|
||||
// LOOKUP_PLAYERS
|
||||
guids: '3u9h9cpfh2yiy4fk',
|
||||
|
||||
// SEND_INVITE_EMAIL
|
||||
inviteeEmailAddress: 'jpg3y4ax7t0w356j',
|
||||
},
|
||||
|
||||
// set 9 - 2013-11-1
|
||||
{
|
||||
'dashboard.getArtifactInfo': 'artifacts', // GET_ARTIFACT_INFO: new (and not obfuscated?!)
|
||||
'dashboard.getGameScore': '9w8phj2dccvns3t9', // GET_GAME_SCORE
|
||||
'dashboard.getPaginatedPlextsV2': '3b1nc3ub0sd1704x', // GET_PAGINATED_PLEXTS
|
||||
'dashboard.getThinnedEntitiesV4': '2xa55qj41qrhfhas', // GET_THINNED_ENTITIES
|
||||
'dashboard.getPlayersByGuids': '734hxjh89d53clqq', // LOOKUP_PLAYERS
|
||||
'dashboard.redeemReward': 'k3hwg41wf112gjjh', // REDEEM_REWARD
|
||||
'dashboard.sendInviteEmail': 'uwizjeb18xmcesa0', // SEND_INVITE_EMAIL
|
||||
'dashboard.sendPlext': '5au1m1hut1gyvnix', // SEND_PLEXT
|
||||
|
||||
// common parameters
|
||||
method: '3sld77nsm0tjmkvi',
|
||||
version: 'xz7q6r3aja5ttvoo', //guessed parameter name - only seen munged
|
||||
version_parameter: 'b121024077de2a0dc6b34119e4440785c9ea5e64', // passed as the value to the above parameter
|
||||
|
||||
// GET_THINNED_ENTITIES
|
||||
quadKeys: '0o6bkrbwevwn6bg1', //guessed parameter name - only seen munged
|
||||
|
||||
// GET_PAGINATED_PLEXTS
|
||||
desiredNumItems: '3fketl1tv01q7vxu',
|
||||
minLatE6: '5i6jhgbv3aq3c4qz',
|
||||
minLngE6: 'pe2io3r932qysg4u',
|
||||
maxLatE6: 'plzyuy89bnlb3pth',
|
||||
maxLngE6: 'q0qq1ooc7sxpynth',
|
||||
minTimestampMs: 'nc282s8hdklv21mw',
|
||||
maxTimestampMs: 'ezrljj0l71gpelpu',
|
||||
chatTab: 'efaznrayv5n3jxs0', //guessed parameter name - only seen munged
|
||||
ascendingTimestampOrder: 'fcmlcb8ya0oa1clk',
|
||||
|
||||
// SEND_PLEXT
|
||||
message: 'jg4ms2i14rgzi02n',
|
||||
latE6: 'nkf3evzpkxkq8l2q',
|
||||
lngE6: '7xoz0xl8se4d1j53',
|
||||
message: '8exta9k7y8huhqmc',
|
||||
latE6: 'kqek161gza3kjcry',
|
||||
lngE6: '3dlxsqrjj2vcmhbc',
|
||||
// chatTab: 'efaznrayv5n3jxs0', //guessed parameter name - only seen munged
|
||||
|
||||
// LOOKUP_PLAYERS
|
||||
guids: 'm4dcrdltldigfo94',
|
||||
// GET_PORTAL_DETAILS
|
||||
guid: 'seg6ohxgnqf9xu9w',
|
||||
|
||||
// SEND_INVITE_EMAIL
|
||||
inviteeEmailAddress: 'rye9be4um2t1z5ts',
|
||||
inviteeEmailAddress: '8exta9k7y8huhqmc',
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
|
||||
var activeRequestMungeSet = undefined;
|
||||
|
||||
|
||||
// in the recent stock site updates, their javascript code has been less obfuscated, but also the munge parameters
|
||||
// change on every release. I can only assume it's now an integrated step in the build/release system, rather
|
||||
@ -158,14 +70,15 @@ function extractMungeFromStock() {
|
||||
var foundMunges = {};
|
||||
|
||||
// these are easy - directly available in variables
|
||||
foundMunges['dashboard.getArtifactInfo'] = nemesis.dashboard.requests.MethodName.GET_ARTIFACT_INFO;
|
||||
foundMunges['dashboard.getGameScore'] = nemesis.dashboard.requests.MethodName.GET_GAME_SCORE;
|
||||
foundMunges['dashboard.getPaginatedPlextsV2'] = nemesis.dashboard.requests.MethodName.GET_PAGINATED_PLEXTS;
|
||||
foundMunges['dashboard.getThinnedEntitiesV4'] = nemesis.dashboard.requests.MethodName.GET_THINNED_ENTITIES;
|
||||
foundMunges['dashboard.getPlayersByGuids'] = nemesis.dashboard.requests.MethodName.LOOKUP_PLAYERS;
|
||||
foundMunges['dashboard.redeemReward'] = nemesis.dashboard.requests.MethodName.REDEEM_REWARD;
|
||||
foundMunges['dashboard.sendInviteEmail'] = nemesis.dashboard.requests.MethodName.SEND_INVITE_EMAIL;
|
||||
foundMunges['dashboard.sendPlext'] = nemesis.dashboard.requests.MethodName.SEND_PLEXT;
|
||||
// NOTE: the .toString() is there so missing variables throw an exception, rather than storing 'undefined'
|
||||
foundMunges['dashboard.getArtifactInfo'] = nemesis.dashboard.requests.MethodName.GET_ARTIFACT_INFO.toString();
|
||||
foundMunges['dashboard.getGameScore'] = nemesis.dashboard.requests.MethodName.GET_GAME_SCORE.toString();
|
||||
foundMunges['dashboard.getPaginatedPlexts'] = nemesis.dashboard.requests.MethodName.GET_PAGINATED_PLEXTS.toString();
|
||||
foundMunges['dashboard.getThinnedEntities'] = nemesis.dashboard.requests.MethodName.GET_THINNED_ENTITIES.toString();
|
||||
foundMunges['dashboard.getPortalDetails'] = nemesis.dashboard.requests.MethodName.GET_PORTAL_DETAILS.toString();
|
||||
foundMunges['dashboard.redeemReward'] = nemesis.dashboard.requests.MethodName.REDEEM_REWARD.toString();
|
||||
foundMunges['dashboard.sendInviteEmail'] = nemesis.dashboard.requests.MethodName.SEND_INVITE_EMAIL.toString();
|
||||
foundMunges['dashboard.sendPlext'] = nemesis.dashboard.requests.MethodName.SEND_PLEXT.toString();
|
||||
|
||||
// the rest are trickier - we need to parse the functions of the stock site. these break very often
|
||||
// on site updates
|
||||
@ -218,11 +131,11 @@ function extractMungeFromStock() {
|
||||
var chatTab = result[7] || result[8];
|
||||
if (chatTab != foundMunges.chatTab) throw 'Error: inconsistent munge parsing for chatTab';
|
||||
|
||||
// LOOKUP_PLAYERS
|
||||
var reg = new RegExp('LOOKUP_PLAYERS, {'+mungeRegExpLit+'a}');
|
||||
var result = reg.exec(nemesis.dashboard.network.DataFetcher.prototype.lookupPlayersByGuids.toString());
|
||||
// GET_PORTAL_DETAILS
|
||||
var reg = new RegExp('GET_PORTAL_DETAILS, {'+mungeRegExpLit+'a}');
|
||||
var result = reg.exec(nemesis.dashboard.network.DataFetcher.prototype.getPortalDetails.toString());
|
||||
|
||||
foundMunges.guids = result[1] || result[2];
|
||||
foundMunges.guid = result[1] || result[2];
|
||||
|
||||
// SEND_INVITE_EMAIL
|
||||
var reg = new RegExp('SEND_INVITE_EMAIL, {'+mungeRegExpLit+'b}');
|
||||
@ -244,44 +157,32 @@ window.detectActiveMungeSet = function() {
|
||||
// first, try and parse the stock functions and extract the munges directly
|
||||
activeMunge = extractMungeFromStock();
|
||||
if (activeMunge) {
|
||||
console.log('IITC: Successfully extracted munges from stock javascript');
|
||||
return;
|
||||
}
|
||||
|
||||
// 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.doSendRequest_.toString();
|
||||
} catch(e) {
|
||||
try {
|
||||
stockFunc = nemesis.dashboard.network.XhrController.prototype.sendRequest.toString();
|
||||
} catch(e) {
|
||||
try {
|
||||
stockFunc = nemesis.dashboard.network.DataFetcher.prototype.sendRequest_.toString();
|
||||
} catch(e) {
|
||||
console.warn('Failed to find a relevant function in the stock site');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(stockFunc) {
|
||||
for (var i in requestParameterMunges) {
|
||||
if (stockFunc.indexOf (requestParameterMunges[i]['method']) >= 0) {
|
||||
console.log('IITC: found request munge set index '+i+' in stock intel site');
|
||||
activeRequestMungeSet = i;
|
||||
}
|
||||
}
|
||||
console.log('IITC: Successfully extracted munges from stock javascript - excellent work!');
|
||||
} else {
|
||||
console.error('IITC: failed to find the stock site function for detecting munge set');
|
||||
console.warn('IITC: failed to detect a munge set from the code - searching our list...');
|
||||
|
||||
// try to find a matching munge set from the pre-defined ones. this code remains as in the case of
|
||||
// things breaking it can be quicker to update the table than to fix the regular expressions used
|
||||
// above
|
||||
|
||||
try {
|
||||
for (var i in requestParameterMunges) {
|
||||
if (requestParameterMunges[i]['dashboard.getThinnedEntities'] == nemesis.dashboard.requests.MethodName.GET_THINNED_ENTITIES) {
|
||||
console.log('IITC: found a match with munge set index '+i);
|
||||
activeMunge = requestParameterMunges[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
console.warn('IITC: failed to find matching munge set from supplied list');
|
||||
}
|
||||
}
|
||||
|
||||
if (activeRequestMungeSet===undefined) {
|
||||
console.error('IITC: failed to find request munge set - IITC will likely fail');
|
||||
activeRequestMungeSet = 0;
|
||||
if (!activeMunge) {
|
||||
console.warn('IITC: Error!! failed to find a parameter munge set - neither extracting from stock, or searching through table. IITC CANNOT WORK');
|
||||
throw {error:'Failed to find a munge set'};
|
||||
}
|
||||
|
||||
activeMunge = requestParameterMunges[activeRequestMungeSet];
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,152 +1,18 @@
|
||||
// PLAYER NAMES //////////////////////////////////////////////////////
|
||||
// Player names are cached in sessionStorage. There is no GUI
|
||||
// element from within the total conversion to clean them, but you
|
||||
// can run sessionStorage.clean() to reset it.
|
||||
|
||||
|
||||
window.setupPlayerNameCache = function() {
|
||||
// IITC used to store player names in localStorage rather than sessionStorage. lets clear out any cached
|
||||
// names from session storage
|
||||
var matchPlayerGuid = new RegExp ('^[0-9a-f]{32}\\.c$');
|
||||
|
||||
$.each(Object.keys(localStorage), function(ind,key) {
|
||||
if ( matchPlayerGuid.test(key) ) {
|
||||
// copy from localStorage to sessionStorage if not already there
|
||||
if (!sessionStorage[key]) sessionStorage[key] = localStorage[key];
|
||||
// then clear from localStorage
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
// retrieves player name by GUID. If the name is not yet available, it
|
||||
// will be added to a global list of GUIDs that need to be resolved.
|
||||
// The resolve method is not called automatically.
|
||||
window.getPlayerName = function(guid) {
|
||||
if(sessionStorage[guid]) return sessionStorage[guid];
|
||||
// only add to queue if it isn’t already
|
||||
if(playersToResolve.indexOf(guid) === -1 && playersInResolving.indexOf(guid) === -1) {
|
||||
playersToResolve.push(guid);
|
||||
}
|
||||
return '{'+guid.slice(0, 12)+'}';
|
||||
}
|
||||
|
||||
window._playerNameToGuidCache = {};
|
||||
|
||||
window.playerNameToGuid = function(playerName) {
|
||||
var cachedGuid = window._playerNameToGuidCache[playerName];
|
||||
if (cachedGuid !== undefined) return cachedGuid;
|
||||
|
||||
// IITC needs our own player GUID, from a lookup by name. so we retrieve this from localstorage (if available)
|
||||
if (playerName == PLAYER.nickname) {
|
||||
cachedGuid = localStorage['PLAYER-'+PLAYER.nickname];
|
||||
if (cachedGuid !== undefined) return cachedGuid;
|
||||
}
|
||||
|
||||
var guid = null;
|
||||
$.each(Object.keys(sessionStorage), function(ind,key) {
|
||||
if(playerName === sessionStorage[key]) {
|
||||
guid = key;
|
||||
window._playerNameToGuidCache[playerName] = guid;
|
||||
return false; //break from $.each
|
||||
}
|
||||
});
|
||||
|
||||
return guid;
|
||||
}
|
||||
|
||||
// resolves all player GUIDs that have been added to the list. Reruns
|
||||
// renderPortalDetails when finished, so that then-unresolved names
|
||||
// get replaced by their correct versions.
|
||||
window.resolvePlayerNames = function() {
|
||||
if(window.playersToResolve.length === 0) return;
|
||||
|
||||
//limit per request. stock site is never more than 13 (8 res, 4 mods, owner)
|
||||
//testing shows 15 works and 20 fails
|
||||
var MAX_RESOLVE_PLAYERS_PER_REQUEST = 15;
|
||||
var MAX_RESOLVE_REQUESTS = 8;
|
||||
|
||||
if (window.playersToResolve.length > MAX_RESOLVE_PLAYERS_PER_REQUEST*MAX_RESOLVE_REQUESTS) {
|
||||
console.log('Warning: player name resolve queue had '+window.playersToResolve.length+' entries. Limiting to the first '+MAX_RESOLVE_PLAYERS_PER_REQUEST*MAX_RESOLVE_REQUESTS+' to prevent excessive requests');
|
||||
window.playersToResolve = playersToResolve.slice(0,MAX_RESOLVE_PLAYERS_PER_REQUEST*MAX_RESOLVE_REQUESTS);
|
||||
}
|
||||
|
||||
var p = window.playersToResolve.slice(0,MAX_RESOLVE_PLAYERS_PER_REQUEST);
|
||||
window.playersToResolve = playersToResolve.slice(MAX_RESOLVE_PLAYERS_PER_REQUEST);
|
||||
|
||||
var d = {guids: p};
|
||||
window.playersInResolving = window.playersInResolving.concat(p);
|
||||
|
||||
postAjax('getPlayersByGuids', d, function(dat) {
|
||||
var resolvedName = {};
|
||||
if(dat.result) {
|
||||
$.each(dat.result, function(ind, player) {
|
||||
window.setPlayerName(player.guid, player.nickname);
|
||||
resolvedName[player.guid] = player.nickname;
|
||||
// remove from array
|
||||
window.playersInResolving.splice(window.playersInResolving.indexOf(player.guid), 1);
|
||||
});
|
||||
} else {
|
||||
//no 'result' - a successful http request, but the returned result was an error of some kind
|
||||
console.warn('getplayers problem - no result in response: '+dat);
|
||||
|
||||
//likely to be some kind of 'bad request' (e.g. too many names at once, or otherwise badly formatted data.
|
||||
//therefore, not a good idea to automatically retry by adding back to the playersToResolve list
|
||||
}
|
||||
|
||||
// Run hook 'playerNameResolved' with the resolved player names
|
||||
window.runHooks('playerNameResolved', {names: resolvedName});
|
||||
|
||||
//TODO: have an event triggered for this instead of hard-coded single function call
|
||||
if(window.selectedPortal)
|
||||
window.renderPortalDetails(window.selectedPortal);
|
||||
|
||||
//if more to do, run again
|
||||
if(window.playersToResolve.length>0) resolvePlayerNames();
|
||||
},
|
||||
function() {
|
||||
// append failed resolves to the list again
|
||||
console.warn('resolving player guids failed: ' + p.join(', '));
|
||||
window.playersToResolve.concat(p);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
window.setPlayerName = function(guid, nick, uncertain) {
|
||||
// the 'uncertain' flag is set when we're scrolling back through chat. it's possible in this case
|
||||
// to come across a message from before a name change. these should be ignored if existing cache entries exist
|
||||
if(uncertain && guid in sessionStorage) return;
|
||||
|
||||
if($.trim(('' + nick)).slice(0, 5) === '{"L":' && !window.alertFor37WasShown) {
|
||||
window.alertFor37WasShown = true;
|
||||
alert('You have run into bug #37. Please help me solve it!\nCopy and paste this text and post it here:\nhttps://github.com/breunigs/ingress-intel-total-conversion/issues/37\nIf copy & pasting doesn’t work, make a screenshot instead.\n\n\n' + window.debug.printStackTrace() + '\n\n\n' + JSON.stringify(nick));
|
||||
}
|
||||
sessionStorage[guid] = nick;
|
||||
|
||||
// IITC needs our own player ID early on in startup. the only way we can find this is by something else
|
||||
// doing a guid->name lookup for our own name. as this doesn't always happen - and likely won't happen when needed
|
||||
// we'll store our own name->guid lookup in localStorage
|
||||
if (nick == PLAYER.nickname) {
|
||||
localStorage['PLAYER-'+PLAYER.nickname] = guid;
|
||||
PLAYER.guid = guid; // set it in PLAYER in case it wasn't already done
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// test to see if a specific player GUID is a special system account (e.g. __JARVIS__, __ADA__) that shouldn't
|
||||
// be listed as a player
|
||||
window.isSystemPlayer = function(guid) {
|
||||
window.isSystemPlayer = function(name) {
|
||||
|
||||
switch (guid) {
|
||||
case '00000000000000000000000000000001.c':
|
||||
case '00000000000000000000000000000002.c':
|
||||
switch (name) {
|
||||
case '__ADA__':
|
||||
case '__JARVIS__':
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
81
code/portal_data.js
Normal file
81
code/portal_data.js
Normal file
@ -0,0 +1,81 @@
|
||||
/// PORTAL DATA TOOLS ///////////////////////////////////////////////////
|
||||
// misc functions to get portal info
|
||||
|
||||
// search through the links data for all that link from or to a portal. returns an object with separate lists of in
|
||||
// and out links. may or may not be as accurate as the portal details, depending on how much data the API returns
|
||||
window.getPortalLinks = function(guid) {
|
||||
|
||||
var links = { in: [], out: [] };
|
||||
|
||||
$.each(window.links, function(g,l) {
|
||||
var d = l.options.data;
|
||||
|
||||
if (d.oGuid == guid) {
|
||||
links.out.push(g);
|
||||
}
|
||||
if (d.dGuid == guid) {
|
||||
links.in.push(g);
|
||||
}
|
||||
});
|
||||
|
||||
return links;
|
||||
}
|
||||
|
||||
|
||||
// search through the fields for all that reference a portal
|
||||
window.getPortalFields = function(guid) {
|
||||
var fields = [];
|
||||
|
||||
$.each(window.fields, function(g,f) {
|
||||
var d = f.options.data;
|
||||
|
||||
if ( d.points[0].guid == guid
|
||||
|| d.points[1].guid == guid
|
||||
|| d.points[2].guid == guid ) {
|
||||
|
||||
fields.push(g);
|
||||
}
|
||||
});
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
|
||||
// find the lat/lon for a portal, using any and all available data
|
||||
// (we have the list of portals, the cached portal details, plus links and fields as sources of portal locations)
|
||||
window.findPortalLatLng = function(guid) {
|
||||
if (window.portals[guid]) {
|
||||
return window.portals[guid].getLatLng();
|
||||
}
|
||||
|
||||
// not found in portals - try the cached (and possibly stale) details - good enough for location
|
||||
var details = portalDetail.get(guid);
|
||||
if (details) {
|
||||
return L.latLng (details.locationE6.latE6/1E6, details.locationE6.lngE6/1E6);
|
||||
}
|
||||
|
||||
// now try searching through fields
|
||||
for (var fguid in window.fields) {
|
||||
var f = window.fields[fguid].options.data;
|
||||
|
||||
for (var i in f.points) {
|
||||
if (f.points[i].guid == guid) {
|
||||
return L.latLng (f.points[i].latE6/1E6, f.points[i].lngE6/1E6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// and finally search through links
|
||||
for (var lguid in window.links) {
|
||||
var l = window.links[lguid].options.data;
|
||||
if (l.oGuid == guid) {
|
||||
return L.latLng (l.oLatE6/1E6, l.oLngE6/1E6);
|
||||
}
|
||||
if (l.dGuid == guid) {
|
||||
return L.latLng (l.dLatE6/1E6, l.dLngE6/1E6);
|
||||
}
|
||||
}
|
||||
|
||||
// no luck finding portal lat/lng
|
||||
return undefined;
|
||||
}
|
59
code/portal_detail.js
Normal file
59
code/portal_detail.js
Normal file
@ -0,0 +1,59 @@
|
||||
/// PORTAL DETAIL //////////////////////////////////////
|
||||
// code to retrieve the new potal detail data from the servers
|
||||
|
||||
// NOTE: the API for portal detailed information is NOT FINAL
|
||||
// this is a temporary measure to get things working again after a major change to the intel map
|
||||
// API. expect things to change here
|
||||
|
||||
|
||||
// anonymous function wrapper for the code - any variables/functions not placed into 'window' will be private
|
||||
(function(){
|
||||
|
||||
var cache;
|
||||
|
||||
|
||||
window.portalDetail = function() {};
|
||||
|
||||
window.portalDetail.setup = function() {
|
||||
cache = new DataCache();
|
||||
|
||||
cache.startExpireInterval(20);
|
||||
}
|
||||
|
||||
window.portalDetail.get = function(guid) {
|
||||
return cache.get(guid);
|
||||
}
|
||||
|
||||
window.portalDetail.isFresh = function(guid) {
|
||||
return cache.isFresh(guid);
|
||||
}
|
||||
|
||||
|
||||
var handleResponse = function(guid, data, success) {
|
||||
|
||||
if (success) {
|
||||
cache.store(guid,data);
|
||||
|
||||
//FIXME..? better way of handling sidebar refreshing...
|
||||
|
||||
if (guid == selectedPortal) {
|
||||
renderPortalDetails(guid);
|
||||
}
|
||||
}
|
||||
|
||||
window.runHooks ('portalDetailLoaded', {guid:guid, success:success, details:data});
|
||||
}
|
||||
|
||||
window.portalDetail.request = function(guid) {
|
||||
|
||||
window.postAjax('getPortalDetails', {guid:guid},
|
||||
function(data,textStatus,jqXHR) { handleResponse(guid, data, true); },
|
||||
function() { handleResponse(guid, undefined, false); }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
})(); // anonumous wrapper function end
|
||||
|
||||
|
@ -5,79 +5,45 @@
|
||||
window.renderPortalDetails = function(guid) {
|
||||
selectPortal(window.portals[guid] ? guid : null);
|
||||
|
||||
if (!portalDetail.isFresh(guid)) {
|
||||
portalDetail.request(guid);
|
||||
}
|
||||
|
||||
// TODO? handle the case where we request data for a particular portal GUID, but it *isn't* in
|
||||
// window.portals....
|
||||
|
||||
if(!window.portals[guid]) {
|
||||
urlPortal = guid;
|
||||
$('#portaldetails').html('');
|
||||
if(isSmartphone()) {
|
||||
$('.fullimg').remove();
|
||||
$('#mobileinfo').html('');
|
||||
$('#mobileinfo').html('<div style="text-align: center"><b>tap here for info screen</b></div>');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var d = window.portals[guid].options.details;
|
||||
|
||||
// collect some random data that’s not worth to put in an own method
|
||||
var links = {incoming: 0, outgoing: 0};
|
||||
if(d.portalV2.linkedEdges) $.each(d.portalV2.linkedEdges, function(ind, link) {
|
||||
links[link.isOrigin ? 'outgoing' : 'incoming']++;
|
||||
});
|
||||
function linkExpl(t) { return '<tt title="↳ incoming links\n↴ outgoing links\n• is the portal">'+t+'</tt>'; }
|
||||
var linksText = [linkExpl('links'), linkExpl(' ↳ ' + links.incoming+' • '+links.outgoing+' ↴')];
|
||||
|
||||
var player = d.captured && d.captured.capturingPlayerId
|
||||
? '<span class="nickname">' + getPlayerName(d.captured.capturingPlayerId) + '</span>'
|
||||
: null;
|
||||
var playerText = player ? ['owner', player] : null;
|
||||
|
||||
var time = d.captured
|
||||
? '<span title="' + unixTimeToDateTimeString(d.captured.capturedTime, false) + '\n'
|
||||
+ formatInterval(Math.floor((Date.now()-d.captured.capturedTime)/1000), 2) + ' ago">'
|
||||
+ unixTimeToString(d.captured.capturedTime) + '</span>'
|
||||
: null;
|
||||
var sinceText = time ? ['since', time] : null;
|
||||
|
||||
var linkedFields = ['fields', d.portalV2.linkedFields ? d.portalV2.linkedFields.length : 0];
|
||||
|
||||
// collect and html-ify random data
|
||||
var randDetails = [
|
||||
playerText, sinceText,
|
||||
getRangeText(d), getEnergyText(d),
|
||||
linksText, getAvgResoDistText(d),
|
||||
linkedFields, getAttackApGainText(d),
|
||||
getHackDetailsText(d), getMitigationText(d)
|
||||
];
|
||||
|
||||
// artifact details
|
||||
|
||||
//niantic hard-code the fact it's just jarvis shards/targets - so until more examples exist, we'll do the same
|
||||
//(at some future point we can iterate through all the artifact types and add rows as needed)
|
||||
var jarvisArtifact = artifact.getPortalData (guid, 'jarvis');
|
||||
if (jarvisArtifact) {
|
||||
// the genFourColumnTable function below doesn't handle cases where one column is null and the other isn't - so default to *something* in both columns
|
||||
var target = ['',''], shards = ['shards','(none)'];
|
||||
if (jarvisArtifact.target) {
|
||||
target = ['target', '<span class="'+TEAM_TO_CSS[jarvisArtifact.target]+'">'+(jarvisArtifact.target==TEAM_RES?'Resistance':'Enlightened')+'</span>'];
|
||||
}
|
||||
if (jarvisArtifact.fragments) {
|
||||
shards = [jarvisArtifact.fragments.length>1?'shards':'shard', '#'+jarvisArtifact.fragments.join(', #')];
|
||||
}
|
||||
|
||||
randDetails.push (target, shards);
|
||||
}
|
||||
var portal = window.portals[guid];
|
||||
var data = portal.options.data;
|
||||
var details = portalDetail.get(guid);
|
||||
|
||||
|
||||
randDetails = '<table id="randdetails">' + genFourColumnTable(randDetails) + '</table>';
|
||||
var modDetails = details ? '<div class="mods">'+getModDetails(details)+'</div>' : '';
|
||||
var miscDetails = details ? getPortalMiscDetails(guid,details) : '';
|
||||
var resoDetails = details ? getResonatorDetails(details) : '';
|
||||
|
||||
var resoDetails = '<table id="resodetails">' + getResonatorDetails(d) + '</table>';
|
||||
//TODO? other status details...
|
||||
var statusDetails = details ? '' : '<div id="portalStatus">Loading details...</div>';
|
||||
|
||||
|
||||
var img = getPortalImageUrl(d);
|
||||
var lat = d.locationE6.latE6/1E6;
|
||||
var lng = d.locationE6.lngE6/1E6;
|
||||
var perma = '/intel?ll='+lat+','+lng+'&z=17&pll='+lat+','+lng;
|
||||
var imgTitle = 'title="'+getPortalDescriptionFromDetails(d)+'\n\nClick to show full image."';
|
||||
var poslinks = 'window.showPortalPosLinks('+lat+','+lng+',\''+escapeJavascriptString(d.portalV2.descriptiveText.TITLE)+'\')';
|
||||
var portalDetailObj = window.getPortalDescriptionFromDetailsExtended(d);
|
||||
var img = fixPortalImageUrl(details ? details.imageByUrl && details.imageByUrl.imageUrl : data.image);
|
||||
var title = details ? details.portalV2.descriptiveText.TITLE : data.title;
|
||||
|
||||
var lat = data.latE6/1E6;
|
||||
var lng = data.lngE6/1E6;
|
||||
|
||||
var imgTitle = details ? getPortalDescriptionFromDetails(details) : data.title;
|
||||
imgTitle += '\n\nClick to show full image.';
|
||||
var portalDetailObj = details ? window.getPortalDescriptionFromDetailsExtended(details) : undefined;
|
||||
|
||||
var portalDetailedDescription = '';
|
||||
|
||||
@ -111,74 +77,184 @@ window.renderPortalDetails = function(guid) {
|
||||
portalDetailedDescription += '</table>';
|
||||
}
|
||||
|
||||
var levelDetails = getPortalLevel(d);
|
||||
if(levelDetails != 8) {
|
||||
if(levelDetails==Math.ceil(levelDetails))
|
||||
levelDetails += "\n8";
|
||||
else
|
||||
levelDetails += "\n" + (Math.ceil(levelDetails) - levelDetails)*8;
|
||||
levelDetails += " resonator level(s) needed for next portal level";
|
||||
} else {
|
||||
levelDetails += "\nfully upgraded";
|
||||
// portal level. start with basic data - then extend with fractional info in tooltip if available
|
||||
var levelInt = data ? data.level : getPortalLevel(details);
|
||||
var levelDetails = data.level;
|
||||
if (details) {
|
||||
levelDetails = getPortalLevel(details);
|
||||
if(levelDetails != 8) {
|
||||
if(levelDetails==Math.ceil(levelDetails))
|
||||
levelDetails += "\n8";
|
||||
else
|
||||
levelDetails += "\n" + (Math.ceil(levelDetails) - levelDetails)*8;
|
||||
levelDetails += " resonator level(s) needed for next portal level";
|
||||
} else {
|
||||
levelDetails += "\nfully upgraded";
|
||||
}
|
||||
}
|
||||
levelDetails = "Level " + levelDetails;
|
||||
|
||||
|
||||
var linkDetails = [];
|
||||
|
||||
var posOnClick = 'window.showPortalPosLinks('+lat+','+lng+',\''+escapeJavascriptString(title)+'\')';
|
||||
var permalinkUrl = '/intel?ll='+lat+','+lng+'&z=17&pll='+lat+','+lng;
|
||||
|
||||
if (typeof android !== 'undefined' && android && android.intentPosLink) {
|
||||
// android devices. one share link option - and the android app provides an interface to share the URL,
|
||||
// share as a geo: intent (navigation via google maps), etc
|
||||
|
||||
var shareLink = $('<div>').html( $('<a>').attr({onclick:posOnClick}).text('Share portal') ).html();
|
||||
linkDetails.push('<aside>'+shareLink+'</aside>');
|
||||
|
||||
} else {
|
||||
// non-android - a permalink for the portal
|
||||
var permaHtml = $('<div>').html( $('<a>').attr({href:permalinkUrl, target:'_blank', title:'Create a URL link to this portal'}).text('Portal link') ).html();
|
||||
linkDetails.push ( '<aside>'+permaHtml+'</aside>' );
|
||||
|
||||
// and a map link popup dialog
|
||||
var mapHtml = $('<div>').html( $('<a>').attr({onclick:posOnClick, title:'Link to alternative maps (Google, etc)'}).text('Map links') ).html();
|
||||
linkDetails.push('<aside>'+mapHtml+'</aside>');
|
||||
|
||||
}
|
||||
|
||||
$('#portaldetails')
|
||||
.attr('class', TEAM_TO_CSS[getTeam(d)])
|
||||
.html(''
|
||||
+ '<h3 class="title">'+escapeHtmlSpecialChars(d.portalV2.descriptiveText.TITLE)+'</h3>'
|
||||
+ '<span class="close" onclick="renderPortalDetails(null); if(isSmartphone()) show(\'map\');" title="Close">X</span>'
|
||||
.html('') //to ensure it's clear
|
||||
.attr('class', TEAM_TO_CSS[portal.options.team])
|
||||
.append(
|
||||
$('<h3>').attr({class:'title'}).text(data.title),
|
||||
|
||||
$('<span>').attr({class:'close', onclick:'renderPortalDetails(null); if(isSmartphone()) show("map");',title:'Close'}).text('X'),
|
||||
|
||||
// help cursor via ".imgpreview img"
|
||||
+ '<div class="imgpreview" '+imgTitle+' style="background-image: url('+img+')">'
|
||||
+ '<span id="level" title="'+levelDetails+'">'+Math.floor(getPortalLevel(d))+'</span>'
|
||||
+ '<div class="portalDetails">'+ portalDetailedDescription + '</div>'
|
||||
+ '<img class="hide" src="'+img+'"/></div>'
|
||||
+ '</div>'
|
||||
+ '<div class="mods">'+getModDetails(d)+'</div>'
|
||||
+ randDetails
|
||||
+ resoDetails
|
||||
+ '<div class="linkdetails">'
|
||||
+ (
|
||||
typeof android !== 'undefined' && android && android.intentPosLink // Android handles both links via a dialog
|
||||
? '<aside><a onclick="'+poslinks+'" title="Create a URL link to this portal" >Portal link</a></aside>'
|
||||
: '<aside><a href="'+perma+'" onclick="return androidCopy(this.href)" title="Create a URL link to this portal" >Portal link</a></aside>'
|
||||
+ '<aside><a onclick="'+poslinks+'" title="Link to alternative maps (Google, etc)">Map links</a></aside>'
|
||||
)
|
||||
+ '</div>'
|
||||
$('<div>')
|
||||
.attr({class:'imgpreview', title:imgTitle, style:"background-image: url('"+img+"')"})
|
||||
.append(
|
||||
$('<span>').attr({id:'level', title: levelDetails}).text(levelInt),
|
||||
$('<div>').attr({class:'portalDetails'}).html(portalDetailedDescription),
|
||||
$('<img>').attr({class:'hide', src:img})
|
||||
),
|
||||
|
||||
modDetails,
|
||||
miscDetails,
|
||||
resoDetails,
|
||||
statusDetails,
|
||||
'<div class="linkdetails">' + linkDetails.join('') + '</div>'
|
||||
);
|
||||
|
||||
// try to resolve names that were required for above functions, but
|
||||
// weren't available yet.
|
||||
resolvePlayerNames();
|
||||
|
||||
runHooks('portalDetailsUpdated', {portalDetails: d});
|
||||
// only run the hooks when we have a portalDetails object - most plugins rely on the extended data
|
||||
// TODO? another hook to call always, for any plugins that can work with less data?
|
||||
if (details) {
|
||||
runHooks('portalDetailsUpdated', {guid: guid, portal: portal, portalDetails: details, portalData: data});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
window.getPortalMiscDetails = function(guid,d) {
|
||||
|
||||
var randDetails;
|
||||
|
||||
if (d) {
|
||||
|
||||
// collect some random data that’s not worth to put in an own method
|
||||
var links = {incoming: 0, outgoing: 0};
|
||||
$.each(d.portalV2.linkedEdges||[], function(ind, link) {
|
||||
links[link.isOrigin ? 'outgoing' : 'incoming']++;
|
||||
});
|
||||
|
||||
function linkExpl(t) { return '<tt title="↳ incoming links\n↴ outgoing links\n• is the portal">'+t+'</tt>'; }
|
||||
var linksText = [linkExpl('links'), linkExpl(' ↳ ' + links.incoming+' • '+links.outgoing+' ↴')];
|
||||
|
||||
var player = d.captured && d.captured.capturingPlayerId
|
||||
? '<span class="nickname">' + d.captured.capturingPlayerId + '</span>'
|
||||
: null;
|
||||
var playerText = player ? ['owner', player] : null;
|
||||
|
||||
var time = d.captured
|
||||
? '<span title="' + unixTimeToDateTimeString(d.captured.capturedTime, false) + '\n'
|
||||
+ formatInterval(Math.floor((Date.now()-d.captured.capturedTime)/1000), 2) + ' ago">'
|
||||
+ unixTimeToString(d.captured.capturedTime) + '</span>'
|
||||
: null;
|
||||
var sinceText = time ? ['since', time] : null;
|
||||
|
||||
var linkedFields = ['fields', d.portalV2.linkedFields ? d.portalV2.linkedFields.length : 0];
|
||||
|
||||
// collect and html-ify random data
|
||||
var randDetailsData = [];
|
||||
if (playerText && sinceText) {
|
||||
randDetailsData.push (playerText, sinceText);
|
||||
}
|
||||
|
||||
randDetailsData.push (
|
||||
getRangeText(d), getEnergyText(d),
|
||||
linksText, getAvgResoDistText(d),
|
||||
linkedFields, getAttackApGainText(d),
|
||||
getHackDetailsText(d), getMitigationText(d)
|
||||
);
|
||||
|
||||
// artifact details
|
||||
|
||||
//niantic hard-code the fact it's just jarvis shards/targets - so until more examples exist, we'll do the same
|
||||
//(at some future point we can iterate through all the artifact types and add rows as needed)
|
||||
var jarvisArtifact = artifact.getPortalData (guid, 'jarvis');
|
||||
if (jarvisArtifact) {
|
||||
// the genFourColumnTable function below doesn't handle cases where one column is null and the other isn't - so default to *something* in both columns
|
||||
var target = ['',''], shards = ['shards','(none)'];
|
||||
if (jarvisArtifact.target) {
|
||||
target = ['target', '<span class="'+TEAM_TO_CSS[jarvisArtifact.target]+'">'+(jarvisArtifact.target==TEAM_RES?'Resistance':'Enlightened')+'</span>'];
|
||||
}
|
||||
if (jarvisArtifact.fragments) {
|
||||
shards = [jarvisArtifact.fragments.length>1?'shards':'shard', '#'+jarvisArtifact.fragments.join(', #')];
|
||||
}
|
||||
|
||||
randDetailsData.push (target, shards);
|
||||
}
|
||||
|
||||
randDetails = '<table id="randdetails">' + genFourColumnTable(randDetailsData) + '</table>';
|
||||
|
||||
}
|
||||
|
||||
return randDetails;
|
||||
}
|
||||
|
||||
|
||||
// draws link-range and hack-range circles around the portal with the
|
||||
// given details. Clear them if parameter 'd' is null.
|
||||
window.setPortalIndicators = function(d) {
|
||||
window.setPortalIndicators = function(p) {
|
||||
|
||||
if(portalRangeIndicator) map.removeLayer(portalRangeIndicator);
|
||||
portalRangeIndicator = null;
|
||||
if(portalAccessIndicator) map.removeLayer(portalAccessIndicator);
|
||||
portalAccessIndicator = null;
|
||||
|
||||
if(d === null) return;
|
||||
// if we have a portal...
|
||||
|
||||
var range = getPortalRange(d);
|
||||
var coord = [d.locationE6.latE6/1E6, d.locationE6.lngE6/1E6];
|
||||
portalRangeIndicator = (range.range > 0
|
||||
? L.geodesicCircle(coord, range.range, {
|
||||
fill: false,
|
||||
color: RANGE_INDICATOR_COLOR,
|
||||
weight: 3,
|
||||
dashArray: range.isLinkable ? undefined : "10,10",
|
||||
clickable: false })
|
||||
: L.circle(coord, range.range, { fill: false, stroke: false, clickable: false })
|
||||
if(p) {
|
||||
var coord = p.getLatLng();
|
||||
|
||||
// range is only known for sure if we have portal details
|
||||
// TODO? render a min range guess until details are loaded..?
|
||||
|
||||
var d = portalDetail.get(p.options.guid);
|
||||
if (d) {
|
||||
var range = getPortalRange(d);
|
||||
portalRangeIndicator = (range.range > 0
|
||||
? L.geodesicCircle(coord, range.range, {
|
||||
fill: false,
|
||||
color: RANGE_INDICATOR_COLOR,
|
||||
weight: 3,
|
||||
dashArray: range.isLinkable ? undefined : "10,10",
|
||||
clickable: false })
|
||||
: L.circle(coord, range.range, { fill: false, stroke: false, clickable: false })
|
||||
).addTo(map);
|
||||
}
|
||||
|
||||
portalAccessIndicator = L.circle(coord, HACK_RANGE,
|
||||
{ fill: false, color: ACCESS_INDICATOR_COLOR, weight: 2, clickable: false }
|
||||
).addTo(map);
|
||||
}
|
||||
|
||||
portalAccessIndicator = L.circle(coord, HACK_RANGE,
|
||||
{ fill: false, color: ACCESS_INDICATOR_COLOR, weight: 2, clickable: false }
|
||||
).addTo(map);
|
||||
}
|
||||
|
||||
// highlights portal with given GUID. Automatically clears highlights
|
||||
@ -205,7 +281,7 @@ window.selectPortal = function(guid) {
|
||||
}
|
||||
}
|
||||
|
||||
setPortalIndicators(newPortal ? newPortal.options.details : null);
|
||||
setPortalIndicators(newPortal);
|
||||
|
||||
runHooks('portalSelected', {selectedPortalGuid: guid, unselectedPortalGuid: oldPortalGuid});
|
||||
return update;
|
||||
|
@ -29,8 +29,8 @@ window.getPortalDescriptionFromDetails = function(details) {
|
||||
var desc = descObj.TITLE;
|
||||
if(descObj.ADDRESS)
|
||||
desc += '\n' + descObj.ADDRESS;
|
||||
if(descObj.ATTRIBUTION)
|
||||
desc += '\nby '+descObj.ATTRIBUTION+' ('+descObj.ATTRIBUTION_LINK+')';
|
||||
// if(descObj.ATTRIBUTION)
|
||||
// desc += '\nby '+descObj.ATTRIBUTION+' ('+descObj.ATTRIBUTION_LINK+')';
|
||||
return desc;
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ window.getModDetails = function(d) {
|
||||
|
||||
modTooltip = modName + '\n';
|
||||
if (mod.installingUser) {
|
||||
modTooltip += 'Installed by: '+ getPlayerName(mod.installingUser) + '\n';
|
||||
modTooltip += 'Installed by: '+ mod.installingUser + '\n';
|
||||
}
|
||||
|
||||
if (mod.stats) {
|
||||
@ -176,7 +176,7 @@ window.getResonatorDetails = function(d) {
|
||||
|
||||
var l = parseInt(reso.level);
|
||||
var v = parseInt(reso.energyTotal);
|
||||
var nick = window.getPlayerName(reso.ownerGuid);
|
||||
var nick = reso.ownerGuid;
|
||||
var dist = reso.distanceToPortal;
|
||||
// if array order and slot order drift apart, at least the octant
|
||||
// naming will still be correct.
|
||||
@ -184,7 +184,8 @@ window.getResonatorDetails = function(d) {
|
||||
|
||||
resoDetails.push(renderResonatorDetails(slot, l, v, dist, nick));
|
||||
});
|
||||
return genFourColumnTable(resoDetails);
|
||||
return '<table id="resodetails">' + genFourColumnTable(resoDetails) + '</table>';
|
||||
|
||||
}
|
||||
|
||||
// helper function that renders the HTML for a given resonator. Does
|
||||
|
@ -112,7 +112,8 @@ window.getAttackApGain = function(d) {
|
||||
return true;
|
||||
resoCount += 1;
|
||||
var reslevel=parseInt(reso.level);
|
||||
if(reso.ownerGuid === PLAYER.guid) {
|
||||
// NOTE: reso.ownerGuid is actually the name - no player GUIDs are visible in the protocol any more
|
||||
if(reso.ownerGuid === PLAYER.nickname) {
|
||||
if(maxResonators[reslevel] > 0) {
|
||||
maxResonators[reslevel] -= 1;
|
||||
}
|
||||
@ -167,7 +168,8 @@ window.potentialPortalLevel = function(d) {
|
||||
player_resontators[i] = i > PLAYER.level ? 0 : MAX_RESO_PER_PLAYER[i];
|
||||
}
|
||||
$.each(resonators_on_portal, function(ind, reso) {
|
||||
if(reso !== null && reso.ownerGuid === window.PLAYER.guid) {
|
||||
// NOTE: reso.ownerGuid is actually the player name - GUIDs are not in the protocol any more
|
||||
if(reso !== null && reso.ownerGuid === window.PLAYER.nickname) {
|
||||
player_resontators[reso.level]--;
|
||||
}
|
||||
resonator_levels.push(reso === null ? 0 : reso.level);
|
||||
@ -194,10 +196,8 @@ window.potentialPortalLevel = function(d) {
|
||||
}
|
||||
|
||||
|
||||
window.getPortalImageUrl = function(d) {
|
||||
if (d.imageByUrl && d.imageByUrl.imageUrl) {
|
||||
url = d.imageByUrl.imageUrl;
|
||||
|
||||
window.fixPortalImageUrl = function(url) {
|
||||
if (url) {
|
||||
if (window.location.protocol === 'https:') {
|
||||
url = url.indexOf('www.panoramio.com') !== -1
|
||||
? url.replace(/^http:\/\/www/, 'https://ssl').replace('small', 'medium')
|
||||
|
@ -281,7 +281,7 @@ window.getMinPortalLevelForZoom = function(z) {
|
||||
// these values are from the stock intel map. however, they're too detailed for reasonable speed, and increasing
|
||||
// detail at a higher zoom level shows enough detail still, AND speeds up IITC considerably
|
||||
//var ZOOM_TO_LEVEL = [8, 8, 8, 8, 7, 7, 6, 6, 5, 4, 4, 3, 3, 2, 2, 1, 1];
|
||||
var ZOOM_TO_LEVEL = [8, 8, 8, 8, 8, 8, 7, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1];
|
||||
var ZOOM_TO_LEVEL = [8, 8, 8, 8, 8, 7, 7, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1];
|
||||
|
||||
var l = ZOOM_TO_LEVEL[z] || 0;
|
||||
return l;
|
||||
|
Reference in New Issue
Block a user