diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..3bfaabb2 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# Specification available at: http://editorconfig.org + +# Root config file for IITC. +root = true + +[*.{js,py}] +charset = utf-8 +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +# Following JS code style rules do not have EditorConfig support yet: +# - Use identity operators (===) over equality operators (==). +# - Opening brace at end of line. e.g. "if(a) {", "} else {", "} else if (b) }" +# - No space between keyword and parentheses. "if(a)" not "if (a)" +# - Use single-quotes for strings, and double-quotes within strings for HTML attribute values. $('
'). diff --git a/.gitignore b/.gitignore index 55ccd51b..8caa354d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,22 @@ localbuildsettings.py *.bak *.project .pydevproject + +### JetBrains IDE Ignores ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific files: +.idea/workspace.xml +.idea/tasks.xml +.idea/dictionaries +.idea/vcs.xml +.idea/jsLibraryMappings.xml + +# Sensitive or high-churn files: +.idea/dataSources.ids +.idea/dataSources.xml +.idea/dataSources.local.xml +.idea/sqlDataSources.xml +.idea/dynamic.xml +.idea/uiDesigner.xml \ No newline at end of file diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml new file mode 100644 index 00000000..0dc2a318 --- /dev/null +++ b/.idea/codeStyleSettings.xml @@ -0,0 +1,41 @@ + + + + + + \ No newline at end of file diff --git a/.idea/ingress-intel-total-conversion.iml b/.idea/ingress-intel-total-conversion.iml new file mode 100644 index 00000000..75c5adab --- /dev/null +++ b/.idea/ingress-intel-total-conversion.iml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..6501c5e1 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 00000000..3b312839 --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..257af3d1 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/HACKING.md b/HACKING.md index 2ea4bfcf..a8fdd8c5 100644 --- a/HACKING.md +++ b/HACKING.md @@ -73,7 +73,7 @@ How do I report bugs? You can also try to [install the most recent developer version (“nightly”)] (https://www.dropbox.com/sh/lt9p0s40kt3cs6m/3xzpyiVBnF) and repeat the steps above. Maybe your issue has already been fixed? The nightly versions will update to the next stable release, so you don’t need to worry about that. -If your issue persists, continue. The next step is to look for existing issues, maybe someone else has a similar problem. You can look [through the existing issues](https://github.com/jonatkins/ingress-intel-total-conversion/issues?sort=updated&state=open) or use the search function on the top right. If your issue persists, open a new issue and provide **all** of the information below, even if you don’t think this is necessary. +If your issue persists, continue. The next step is to look for existing issues, maybe someone else has a similar problem. You can look [through the existing issues](https://github.com/iitc-project/ingress-intel-total-conversion/issues?sort=updated&state=open) or use the search function on the top right. If your issue persists, open a new issue and provide **all** of the information below, even if you don’t think this is necessary. - a descriptive title - your browser and its version @@ -85,7 +85,7 @@ If your issue persists, continue. The next step is to look for existing issues, - description of how the script behaves now and how it should behave instead -[You may report the issue here.](https://github.com/jonatkins/ingress-intel-total-conversion/issues/new) +[You may report the issue here.](https://github.com/iitc-project/ingress-intel-total-conversion/issues/new) If asked to **“copy console output”**, do the following: diff --git a/LICENSE b/LICENSE index d66cfaed..2ff27d91 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,5 @@ +ISC License + Copyright © 2013 Stefan Breunig Permission to use, copy, modify, and/or distribute this software for diff --git a/README.md b/README.md index 509ecd94..4ffe3aca 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,11 @@ ingress intel total conversion (IITC) ===================================== Since the [breunigs](https://github.com/breunigs/ingress-intel-total-conversion) IITC branch was deleted, -I've created this one to continue some development. +[Jon Atkins](https://github.com/jonatkins) created this one to continue some development. ## Users -Just want to download/install IITC? Go to http://iitc.jonatkins.com/ +Just want to download/install IITC? Go to http://iitc.me/ For keeping up with the latest news, release announcements, etc, Follow IITC on G+ https://plus.google.com/105383756361375410867/posts @@ -15,7 +15,7 @@ If you have questions, need help or advice with IITC, the Google+ community is a https://plus.google.com/communities/105647403088015055797 Want to report a bug? Post it to the issues page -https://github.com/jonatkins/ingress-intel-total-conversion/issues +https://github.com/iitc-project/ingress-intel-total-conversion/issues ## Developers @@ -28,12 +28,12 @@ build correctly on Linux and Windows (and, probably, Macs, FreeBSD, etc) Fork this project, clone to your local machine. -Run the ```build.py local``` script to build the code. +Run the `build.py local` script to build the code. -If all goes well, output of the build will end up in ```build/local``` subfolder. +If all goes well, output of the build will end up in `build/local` subfolder. -You can create a custom build settings file, ```localbuildsettings.py``` - look in the supplied -```buildsettings.py``` for details. +You can create a custom build settings file, `localbuildsettings.py` - look in the supplied +`buildsettings.py` for details. #### Mobile @@ -42,7 +42,7 @@ To build the mobile app, along with python, you will need - The Java JDK (development kit - the runtime JRE is not enough) - The Android SDK -Run ``build.py mobile``` to build IITC Mobile in debug mode. +Run `build.py mobile` to build IITC Mobile in debug mode. -Note that part of the build.py process includes copying the IITC script files into the ```mobile/res``` subfolder. +Note that part of the build.py process includes copying the IITC script files into the `mobile/res` subfolder. If this isn't done (e.g. you build IITC Mobile directly from Eclipse) you will end up with a broken build. diff --git a/build.py b/build.py index 55a6bbf6..c0151306 100755 --- a/build.py +++ b/build.py @@ -235,6 +235,9 @@ main = doReplacements(main,downloadUrl=downloadUrl,updateUrl=updateUrl) saveScriptAndMeta(main, outDir, 'total-conversion-build.user.js', oldDir) +with io.open(os.path.join(outDir, '.build-timestamp'), 'w') as f: + f.write(u"" + time.strftime('%Y-%m-%d %H:%M:%S UTC', utcTime)) + # for each plugin, load, parse, and save output os.mkdir(os.path.join(outDir,'plugins')) diff --git a/code/boot.js b/code/boot.js index 905182cb..5dd4858b 100644 --- a/code/boot.js +++ b/code/boot.js @@ -115,13 +115,21 @@ function createDefaultBaseMapLayers() { //OpenStreetMap attribution - required by several of the layers osmAttribution = 'Map data © OpenStreetMap contributors'; - //MapQuest offer tiles - http://developer.mapquest.com/web/products/open/map - //their usage policy has no limits (except required notification above 4000 tiles/sec - we're perhaps at 50 tiles/sec based on CloudMade stats) - var mqSubdomains = [ 'otile1','otile2', 'otile3', 'otile4' ]; - var mqTileUrlPrefix = window.location.protocol !== 'https:' ? 'http://{s}.mqcdn.com' : 'https://{s}-s.mqcdn.com'; - var mqMapOpt = {attribution: osmAttribution+', Tiles Courtesy of MapQuest', maxNativeZoom: 18, maxZoom: 21, subdomains: mqSubdomains}; - baseLayers['MapQuest OSM'] = new L.TileLayer(mqTileUrlPrefix+'/tiles/1.0.0/map/{z}/{x}/{y}.jpg',mqMapOpt); + // MapQuest - http://developer.mapquest.com/web/products/open/map + // now requires an API key + //var mqSubdomains = [ 'otile1','otile2', 'otile3', 'otile4' ]; + //var mqTileUrlPrefix = window.location.protocol !== 'https:' ? 'http://{s}.mqcdn.com' : 'https://{s}-s.mqcdn.com'; + //var mqMapOpt = {attribution: osmAttribution+', Tiles Courtesy of MapQuest', maxNativeZoom: 18, maxZoom: 21, subdomains: mqSubdomains}; + //baseLayers['MapQuest OSM'] = new L.TileLayer(mqTileUrlPrefix+'/tiles/1.0.0/map/{z}/{x}/{y}.jpg',mqMapOpt); + // MapBox - https://www.mapbox.com/api-documentation/ + // Access MapBox via the GNOME Project proxy. + // In the future, this URL will provide improved tiles from the GNOME Project with localized labels. + var gnomeStreetUrl = 'https://gis.gnome.org/tiles/street/v1/{z}/{x}/{y}'; + var gnomeAerialUrl = 'https://gis.gnome.org/tiles/satellite/v1/{z}/{x}/{y}'; + baseLayers['MapBox Street'] = L.tileLayer(gnomeStreetUrl); + baseLayers['MapBox Satellite'] = L.tileLayer(gnomeAerialUrl); + // cartodb has some nice tiles too - both dark and light subtle maps - http://cartodb.com/basemaps/ // (not available over https though - not on the right domain name anyway) var cartoAttr = '© OpenStreetMap contributors, © CartoDB'; @@ -201,7 +209,7 @@ window.setupMap = function() { portalsFactionLayers[i] = [L.layerGroup(), L.layerGroup(), L.layerGroup()]; portalsLayers[i] = L.layerGroup(portalsFactionLayers[i]); map.addLayer(portalsLayers[i]); - var t = (i === 0 ? 'Unclaimed' : 'Level ' + i) + ' Portals'; + var t = (i === 0 ? 'Unclaimed/Placeholder' : 'Level ' + i) + ' Portals'; addLayers[t] = portalsLayers[i]; // Store it in hiddenLayer to remove later if(!isLayerGroupDisplayed(t, true)) hiddenLayer.push(portalsLayers[i]); @@ -664,7 +672,7 @@ function boot() { $.each(badPlugins,function(name,desc) { warning += '
  • '+name+': '+desc+'
  • '; }); - warning += '

    Please uninstall the problem plugins and reload the page. See this FAQ entry for help.

    Note: It is tricky for IITC to safely disable just problem plugins

    '; + warning += '

    Please uninstall the problem plugins and reload the page. See this FAQ entry for help.

    Note: It is tricky for IITC to safely disable just problem plugins

    '; dialog({ title: 'Plugin Warning', diff --git a/code/hooks.js b/code/hooks.js index 9629647e..9637b7b7 100644 --- a/code/hooks.js +++ b/code/hooks.js @@ -29,6 +29,9 @@ // the Leaflet CircleMarker for the portal in "portal" var. // linkAdded: called when a link is about to be added to the map // fieldAdded: called when a field is about to be added to the map +// portalRemoved: called when a portal has been removed +// linkRemoved: called when a link has been removed +// fieldRemoved: called when a field has been removed // portalDetailsUpdated: fired after the details in the sidebar have // been (re-)rendered Provides data about the portal that // has been selected. @@ -60,6 +63,7 @@ window.VALID_HOOKS = [ 'portalSelected', 'portalDetailsUpdated', 'artifactsUpdated', 'mapDataRefreshStart', 'mapDataEntityInject', 'mapDataRefreshEnd', 'portalAdded', 'linkAdded', 'fieldAdded', + 'portalRemoved', 'linkRemoved', 'fieldRemoved', 'publicChatDataAvailable', 'factionChatDataAvailable', 'requestFinished', 'nicknameClicked', 'geoSearch', 'search', 'iitcLoaded', diff --git a/code/location.js b/code/location.js index 87ac0a27..95d8e561 100644 --- a/code/location.js +++ b/code/location.js @@ -36,6 +36,14 @@ window.getPosition = function() { return {center: new L.LatLng(lat, lng), zoom: z}; } + if(getURLParam('pll')) { + console.log("mappos: reading stock Intel URL portal params"); + var lat = parseFloat(getURLParam('pll').split(",")[0]) || 0.0; + var lng = parseFloat(getURLParam('pll').split(",")[1]) || 0.0; + var z = parseInt(getURLParam('z')) || 17; + return {center: new L.LatLng(lat, lng), zoom: z}; + } + if(readCookie('ingress.intelmap.lat') && readCookie('ingress.intelmap.lng')) { console.log("mappos: reading cookies"); var lat = parseFloat(readCookie('ingress.intelmap.lat')) || 0.0; diff --git a/code/map_data_render.js b/code/map_data_render.js index d3811a15..fd83efcd 100644 --- a/code/map_data_render.js +++ b/code/map_data_render.js @@ -225,6 +225,7 @@ window.Render.prototype.deletePortalEntity = function(guid) { window.ornaments.removePortal(p); this.removePortalFromMapLayer(p); delete window.portals[guid]; + window.runHooks('portalRemoved', {portal: p, data: p.options.data }); } } @@ -233,6 +234,7 @@ window.Render.prototype.deleteLinkEntity = function(guid) { var l = window.links[guid]; linksFactionLayers[l.options.team].removeLayer(l); delete window.links[guid]; + window.runHooks('linkRemoved', {link: l, data: l.options.data }); } } @@ -244,6 +246,7 @@ window.Render.prototype.deleteFieldEntity = function(guid) { fieldsFactionLayers[f.options.team].removeLayer(f); delete window.fields[guid]; + window.runHooks('fieldRemoved', {field: f, data: f.options.data }); } } diff --git a/code/portal_detail_display.js b/code/portal_detail_display.js index dc4793df..94efd037 100644 --- a/code/portal_detail_display.js +++ b/code/portal_detail_display.js @@ -41,7 +41,7 @@ window.renderPortalDetails = function(guid) { var img = fixPortalImageUrl(details ? details.image : data.image); - var title = (details && details.title) || (data && data.title) || '(untitled)'; + var title = (details && details.title) || (data && data.title) || 'null'; var lat = data.latE6/1E6; var lng = data.lngE6/1E6; diff --git a/code/redeeming.js b/code/redeeming.js index bdc929d2..40c956b7 100644 --- a/code/redeeming.js +++ b/code/redeeming.js @@ -168,6 +168,7 @@ window.setupRedeem = function() { if((e.keyCode ? e.keyCode : e.which) !== 13) return; var passcode = $(this).val(); + passcode = passcode.replace(/[^\x20-\x7E]+/g, ''); //removes non-printable characters if(!passcode) return; var jqXHR = window.postAjax('redeemReward', {passcode:passcode}, window.handleRedeemResponse, function(response) { diff --git a/code/search.js b/code/search.js index 120ce055..ced66915 100644 --- a/code/search.js +++ b/code/search.js @@ -7,8 +7,8 @@ addHook('search', function(query) {}); `query` is an object with the following members: - `term` is the term for which the user has searched -- `confirmed` is a boolean indicating if the user has pressed enter after searching. You should not search online or - heavy processing unless the user has confirmed the search term +- `confirmed` is a boolean indicating if the user has pressed enter after searching. You should not search online or + do heavy processing unless the user has confirmed the search term - `addResult(result)` can be called to add a result to the query. `result` may have the following members (`title` is required, as well as one of `position` and `bounds`): @@ -219,6 +219,8 @@ window.search.setup = function() { }); }; + +// search for portals addHook('search', function(query) { var term = query.term.toLowerCase(); var teams = ['NEU','RES','ENL']; @@ -251,21 +253,41 @@ addHook('search', function(query) { }); }); + +// search for locations // TODO: recognize 50°31'03.8"N 7°59'05.3"E and similar formats -// TODO: if a portal with these exact coordinates is found, select it addHook('search', function(query) { - if(query.term.split(',').length == 2) { - var ll = query.term.split(','); - if(!isNaN(ll[0]) && !isNaN(ll[1])) { - query.addResult({ - title: query.term, - description: 'geo coordinates', - position: L.latLng(parseFloat(ll[0]), parseFloat(ll[1])), - }); - } - } + var locations = query.term.match(/[+-]?\d+\.\d+,[+-]?\d+\.\d+/g); + var added = {}; + if(!locations) return; + locations.forEach(function(location) { + var pair = location.split(',').map(function(s) { return parseFloat(s).toFixed(6); }); + var ll = pair.join(","); + var latlng = L.latLng(pair.map(function(s) { return parseFloat(s); })); + if(added[ll]) return; + added[ll] = true; + + query.addResult({ + title: ll, + description: 'geo coordinates', + position: latlng, + onSelected: function(result, event) { + for(var guid in window.portals) { + var p = window.portals[guid].getLatLng(); + if((p.lat.toFixed(6)+","+p.lng.toFixed(6)) == ll) { + renderPortalDetails(guid); + return; + } + } + + urlPortalLL = [result.position.lat, result.position.lng]; + }, + }); + }); }); + +// search on OpenStreetMap addHook('search', function(query) { if(!query.confirmed) return; diff --git a/code/utils_misc.js b/code/utils_misc.js index b3009a58..26ed6826 100644 --- a/code/utils_misc.js +++ b/code/utils_misc.js @@ -38,7 +38,7 @@ window.aboutIITC = function() { + '
    Ingress Intel Total Conversion
    ' + '
    ' + '
    ' - + ' IITC Homepage
    ' + + ' IITC Homepage
    ' + ' On the script’s homepage you can:' + '