app/services/mapService.js
//results get passed to the callback function as second parameter.
results get passed to the callback function as second parameter.
results get passed to the callback function as second parameter .
function searcher(minLat, minLng, boxSize, delta, callback) {
    logger.info("searcher active! latitude: " + minLat + " to " + (minLat+boxSize) + ", longitude: " + minLng + " to " + (minLng+boxSize));
    logger.info("Using proxy number " + proxyPointer + ": " + (proxyPointer === 0 ? "0.0.0.0" : proxyList[proxyPointer-1]));
    var count = 0;
    var promises = [];
    var pokemons = 0;
    var maxCount = Math.round((boxSize/delta)*(boxSize/delta));
    var cb = false;
    for (var i = minLat; i < minLat + boxSize; i = i + delta) {
        for (var j = minLng; j < minLng + boxSize; j = j + delta) {
            var options = baseLink(i, j, delta);
            var proto = collection === 'pokecrew' || collection === 'pokemap' ? https : http;
            var req = proto.request(options, function (response) {
                var deferred = q.defer();
                promises.push(deferred.promise);
                var body = [];
                response.on('data', function (chunk) {
                    body.push(chunk);
                });
                response.on('error', function () {
                    count++;
                    logger.error("Error in HTTP response!");
                });
                response.on('end', function () {
                    count++;
                    try {
                        var data;
                        if (collection === 'fastpokemap') {
                            try {
                                var buf = Buffer.concat(body);
                                data = JSON.parse(zlib.inflateSync(buf).toString('utf8'));
                            } catch (err) {
                                data = JSON.parse(body.toString());
                            }
                        } else {
                            data = JSON.parse(collection === 'pokemap' ? decode(body.toString()) : body.toString());
                        }
                        var arr = [];
                        switch (collection) {
                            case 'pokeRadar':
                                arr = data.data;
                                break;
                            case 'skiplagged':
                                arr = data.pokemons;
                                break;
                            case 'pokecrew':
                                arr = data.seens;
                                break;
                            case 'fastpokemap':
                            case 'pokemap':
                                arr = data;
                                break;
                            default:
                                logger.error("Collection not known!");
                        }
                        if (arr.length > 0) {
                            store.insert(arr);
                            pokemons += arr.length;
                            logger.info(arr.length + " Pokemon in this box!");
                        }
                    } catch (err) {
                    } finally {
                        deferred.resolve();
                    }
                    if(count === maxCount) {
                        if(!cb){
                            cb = true;
                            if (scanType === 'global' && pokemons.length > 0) {
                                coordsFile.push(minLat + "," + minLng);
                            }
                            logger.info('Finished!\n');
                            callback(null, pokemons);
                        }
                    }
                });
            }).setMaxListeners(0);
            req.setTimeout(10000, function() {
                req.abort();
            });
            req.on('error', function(err) {
                count++;
                if(!cb) {
                    cb = true;
                    if (err.code === "ECONNRESET" || err.code === "ETIMEDOUT") {
                        logger.error("Timeout/Connection Reset occured!");
                    } else {
                        logger.error("Request Error occured!", err);
                    }
                    logger.info('Trying again!\n');
                    searcher(minLat, minLng, boxSize, delta, callback);
                }
            });
            req.end();
        }
    }
}
function searcher ( minLat , minLng , boxSize , delta , callback ) { logger . info ( "searcher active! latitude: " + minLat + " to " + ( minLat + boxSize ) + ", longitude: " + minLng + " to " + ( minLng + boxSize ) ) ; logger . info ( "Using proxy number " + proxyPointer + ": " + ( proxyPointer === 0 ? "0.0.0.0" : proxyList [ proxyPointer - 1 ] ) ) ; var count = 0 ; var promises = [ ] ; var pokemons = 0 ; var maxCount = Math . round ( ( boxSize / delta ) * ( boxSize / delta ) ) ; var cb = false ; for ( var i = minLat ; i < minLat + boxSize ; i = i + delta ) { for ( var j = minLng ; j < minLng + boxSize ; j = j + delta ) { var options = baseLink ( i , j , delta ) ; var proto = collection === 'pokecrew' || collection === 'pokemap' ? https : http ; var req = proto . request ( options , function ( response ) { var deferred = q . defer ( ) ; promises . push ( deferred . promise ) ; var body = [ ] ; response . on ( 'data' , function ( chunk ) { body . push ( chunk ) ; } ) ; response . on ( 'error' , function ( ) { count ++ ; logger . error ( "Error in HTTP response!" ) ; } ) ; response . on ( 'end' , function ( ) { count ++ ; try { var data ; if ( collection === 'fastpokemap' ) { try { var buf = Buffer . concat ( body ) ; data = JSON . parse ( zlib . inflateSync ( buf ) . toString ( 'utf8' ) ) ; } catch ( err ) { data = JSON . parse ( body . toString ( ) ) ; } } else { data = JSON . parse ( collection === 'pokemap' ? decode ( body . toString ( ) ) : body . toString ( ) ) ; } var arr = [ ] ; switch ( collection ) { case 'pokeRadar' : arr = data . data ; break ; case 'skiplagged' : arr = data . pokemons ; break ; case 'pokecrew' : arr = data . seens ; break ; case 'fastpokemap' : case 'pokemap' : arr = data ; break ; default : logger . error ( "Collection not known!" ) ; } if ( arr . length > 0 ) { store . insert ( arr ) ; pokemons += arr . length ; logger . info ( arr . length + " Pokemon in this box!" ) ; } } catch ( err ) { } finally { deferred . resolve ( ) ; } if ( count === maxCount ) { if ( ! cb ) { cb = true ; if ( scanType === 'global' && pokemons . length > 0 ) { coordsFile . push ( minLat + "," + minLng ) ; } logger . info ( 'Finished!\n' ) ; callback ( null , pokemons ) ; } } } ) ; } ) . setMaxListeners ( 0 ) ; req . setTimeout ( 10000 , function ( ) { req . abort ( ) ; } ) ; req . on ( 'error' , function ( err ) { count ++ ; if ( ! cb ) { cb = true ; if ( err . code === "ECONNRESET" || err . code === "ETIMEDOUT" ) { logger . error ( "Timeout/Connection Reset occured!" ) ; } else { logger . error ( "Request Error occured!" , err ) ; } logger . info ( 'Trying again!\n' ) ; searcher ( minLat , minLng , boxSize , delta , callback ) ; } } ) ; req . end ( ) ; } } }
results get passed to the callback function as second parameter.
results get passed to the callback function as second parameter .
//count for how many requests finished (either "response.on('end'..." gets triggered or "req.on('error'...") //here found pokemon are stored //maxCount is total number of requests (note that boxSize should be multiple of delta) //flag if callback was already called //loop through box //generate url //generate api call //needed for control flow //stores response //another chunk of data has been received, so append it to `str` //error handling //the whole response has been received, so we append found pokemon //increment response counter //parse the received string into a JSON //check if it uses deflate encoding //if not just parse it as ascii/utf8 //array to hold pokemon //store received pokemon // Redirect or error in response. Unimportant. //logger.error(err); //if all requests are done we can callback //sets timeout of request to 10 seconds, and if so request gets aborted, triggering req.on('error'... //handles error in request or timeout //increment because request has finished with error //request not finished => try again