diff --git a/src/main/java/com/pokegoapi/api/gym/Gym.java b/src/main/java/com/pokegoapi/api/gym/Gym.java index 0b81d426..2c5c53d1 100644 --- a/src/main/java/com/pokegoapi/api/gym/Gym.java +++ b/src/main/java/com/pokegoapi/api/gym/Gym.java @@ -35,7 +35,7 @@ import java.util.ArrayList; import java.util.List; -public class Gym implements MapPoint{ +public class Gym implements MapPoint { private FortData proto; private GetGymDetailsResponse details; private PokemonGo api; diff --git a/src/main/java/com/pokegoapi/api/map/Map.java b/src/main/java/com/pokegoapi/api/map/Map.java index 24b78ff5..612c130e 100644 --- a/src/main/java/com/pokegoapi/api/map/Map.java +++ b/src/main/java/com/pokegoapi/api/map/Map.java @@ -19,6 +19,7 @@ import POGOProtos.Map.Fort.FortDataOuterClass.FortData; import POGOProtos.Map.Fort.FortTypeOuterClass.FortType; import POGOProtos.Map.MapCellOuterClass.MapCell; +import POGOProtos.Map.Pokemon.MapPokemonOuterClass; import POGOProtos.Map.Pokemon.MapPokemonOuterClass.MapPokemon; import POGOProtos.Map.Pokemon.NearbyPokemonOuterClass; import POGOProtos.Map.Pokemon.WildPokemonOuterClass; @@ -38,11 +39,13 @@ import com.annimon.stream.Collectors; import com.annimon.stream.Stream; import com.annimon.stream.function.Function; +import com.annimon.stream.function.Predicate; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import com.pokegoapi.api.PokemonGo; import com.pokegoapi.api.gym.Gym; import com.pokegoapi.api.map.fort.FortDetails; +import com.pokegoapi.api.map.fort.Pokestop; import com.pokegoapi.api.map.pokemon.CatchablePokemon; import com.pokegoapi.api.map.pokemon.NearbyPokemon; import com.pokegoapi.exceptions.LoginFailedException; @@ -52,7 +55,6 @@ import com.pokegoapi.google.common.geometry.S2LatLng; import com.pokegoapi.main.AsyncServerRequest; import com.pokegoapi.main.ServerRequest; -import com.pokegoapi.util.DummyFuture; import com.pokegoapi.util.FutureWrapper; import com.pokegoapi.util.MapUtil; import com.pokegoapi.util.PokemonFuture; @@ -69,6 +71,7 @@ public class Map { private static int RESEND_REQUEST = 5000; private final PokemonGo api; private MapObjects cachedMapObjects; + private List cachedCatchable; private long lastMapUpdate; /** @@ -91,6 +94,11 @@ public Map(PokemonGo api) throws LoginFailedException, RemoteServerException { * @return a List of CatchablePokemon at your current location */ public PokemonFuture> getCatchablePokemonAsync() { + + if (useCache() && cachedCatchable != null) { + return FutureWrapper.just(cachedCatchable); + } + List cellIds = getDefaultCells(); return new FutureWrapper>(getMapObjectsAsync(cellIds)) { @Override @@ -103,13 +111,22 @@ protected List handle(MapObjects mapObjects) throws RemoteServ for (WildPokemonOuterClass.WildPokemon wildPokemon : mapObjects.getWildPokemons()) { catchablePokemons.add(new CatchablePokemon(api, wildPokemon)); } - // TODO: Check if this code is correct; merged because this contains many other fixes - /*for (Pokestop pokestop : objects.getPokestops()) { - if (pokestop.inRange() && pokestop.hasLurePokemon()) { + + /* + TODO: i have more success checking if encounterId > 0 + i don't want to use the hasLure because it do a request every call + */ + for (Pokestop pokestop : mapObjects.getPokestops()) { + if (pokestop.inRange() + && pokestop.getFortData().hasLureInfo() + && pokestop.getFortData().getLureInfo().getEncounterId() > 0) { + //if (pokestop.inRange() && pokestop.hasLurePokemon()) { catchablePokemons.add(new CatchablePokemon(api, pokestop.getFortData())); } - }*/ - return new ArrayList<>(catchablePokemons); + } + + cachedCatchable = new ArrayList<>(catchablePokemons); + return cachedCatchable; } }; } @@ -310,8 +327,8 @@ public PokemonFuture getMapObjectsAsync(int width) { */ public PokemonFuture getMapObjectsAsync(List cellIds) { - if ((api.currentTimeMillis() - lastMapUpdate) < RESEND_REQUEST) { - return new DummyFuture(cachedMapObjects); + if (useCache()) { + return FutureWrapper.just(cachedMapObjects); } lastMapUpdate = api.currentTimeMillis(); @@ -649,6 +666,14 @@ public CatchPokemonResponse catchPokemon( return response; } + /** + * Wether or not to get a fresh copy or use cache; + * + * @return true if enough time has elapsed since the last request, false otherwise + */ + private boolean useCache() { + return (api.currentTimeMillis() - lastMapUpdate) < RESEND_REQUEST; + } private List getDefaultCells() { return getCellIds(api.getLatitude(), api.getLongitude(), CELL_WIDTH); diff --git a/src/main/java/com/pokegoapi/api/map/Point.java b/src/main/java/com/pokegoapi/api/map/Point.java index 13886ea7..2ecb3cad 100644 --- a/src/main/java/com/pokegoapi/api/map/Point.java +++ b/src/main/java/com/pokegoapi/api/map/Point.java @@ -20,7 +20,7 @@ import lombok.Getter; import lombok.Setter; -public class Point implements MapPoint{ +public class Point implements MapPoint { @Getter @Setter private double longitude; diff --git a/src/main/java/com/pokegoapi/api/map/pokemon/CatchablePokemon.java b/src/main/java/com/pokegoapi/api/map/pokemon/CatchablePokemon.java index 5c4a08a0..1c2dd316 100644 --- a/src/main/java/com/pokegoapi/api/map/pokemon/CatchablePokemon.java +++ b/src/main/java/com/pokegoapi/api/map/pokemon/CatchablePokemon.java @@ -15,18 +15,21 @@ package com.pokegoapi.api.map.pokemon; -import POGOProtos.Enums.PokemonIdOuterClass; + +import POGOProtos.Enums.PokemonIdOuterClass.PokemonId; import POGOProtos.Inventory.Item.ItemIdOuterClass.ItemId; import POGOProtos.Map.Fort.FortDataOuterClass.FortData; import POGOProtos.Map.Pokemon.MapPokemonOuterClass.MapPokemon; import POGOProtos.Map.Pokemon.WildPokemonOuterClass.WildPokemon; import POGOProtos.Networking.Requests.Messages.CatchPokemonMessageOuterClass.CatchPokemonMessage; -import POGOProtos.Networking.Requests.Messages.EncounterMessageOuterClass; +import POGOProtos.Networking.Requests.Messages.DiskEncounterMessageOuterClass; +import POGOProtos.Networking.Requests.Messages.DiskEncounterMessageOuterClass.DiskEncounterMessage; +import POGOProtos.Networking.Requests.Messages.EncounterMessageOuterClass.EncounterMessage; import POGOProtos.Networking.Requests.Messages.UseItemCaptureMessageOuterClass.UseItemCaptureMessage; -import POGOProtos.Networking.Requests.RequestTypeOuterClass; +import POGOProtos.Networking.Requests.RequestTypeOuterClass.RequestType; import POGOProtos.Networking.Responses.CatchPokemonResponseOuterClass.CatchPokemonResponse; import POGOProtos.Networking.Responses.CatchPokemonResponseOuterClass.CatchPokemonResponse.CatchStatus; -import POGOProtos.Networking.Responses.EncounterResponseOuterClass; +import POGOProtos.Networking.Responses.DiskEncounterResponseOuterClass.DiskEncounterResponse; import POGOProtos.Networking.Responses.EncounterResponseOuterClass.EncounterResponse; import POGOProtos.Networking.Responses.UseItemCaptureResponseOuterClass.UseItemCaptureResponse; import com.google.protobuf.ByteString; @@ -34,6 +37,9 @@ import com.pokegoapi.api.PokemonGo; import com.pokegoapi.api.inventory.ItemBag; import com.pokegoapi.api.inventory.Pokeball; +import com.pokegoapi.api.map.pokemon.encounter.DiskEncounterResult; +import com.pokegoapi.api.map.pokemon.encounter.EncounterResult; +import com.pokegoapi.api.map.pokemon.encounter.NormalEncounterResult; import com.pokegoapi.exceptions.LoginFailedException; import com.pokegoapi.exceptions.NoSuchItemException; import com.pokegoapi.exceptions.RemoteServerException; @@ -48,11 +54,19 @@ import java.util.concurrent.Future; + /** * The type Catchable pokemon. */ @ToString -public class CatchablePokemon implements MapPoint{ +public class CatchablePokemon implements MapPoint { + + private enum EncounterKind { + NORMAL, + DISK; + } + + private static final String TAG = CatchablePokemon.class.getSimpleName(); private final PokemonGo api; @@ -61,16 +75,19 @@ public class CatchablePokemon implements MapPoint{ @Getter private final long encounterId; @Getter - private final PokemonIdOuterClass.PokemonId pokemonId; + private final PokemonId pokemonId; @Getter private final long expirationTimestampMs; @Getter private final double latitude; @Getter private final double longitude; + private final EncounterKind encounterKind; private Boolean encountered = null; + + /** * Instantiates a new Catchable pokemon. * @@ -79,7 +96,7 @@ public class CatchablePokemon implements MapPoint{ */ public CatchablePokemon(PokemonGo api, MapPokemon proto) { this.api = api; - + this.encounterKind = EncounterKind.NORMAL; this.spawnPointId = proto.getSpawnPointId(); this.encounterId = proto.getEncounterId(); this.pokemonId = proto.getPokemonId(); @@ -96,6 +113,7 @@ public CatchablePokemon(PokemonGo api, MapPokemon proto) { */ public CatchablePokemon(PokemonGo api, WildPokemon proto) { this.api = api; + this.encounterKind = EncounterKind.NORMAL; this.spawnPointId = proto.getSpawnPointId(); this.encounterId = proto.getEncounterId(); this.pokemonId = proto.getPokemonData().getPokemonId(); @@ -116,13 +134,24 @@ public CatchablePokemon(PokemonGo api, FortData proto) { } this.api = api; // TODO: does this work? - this.spawnPointId = null; + // seems that spawnPoint it's fortId in catchAPI so it should be safe to just set it in that way + this.spawnPointId = proto.getLureInfo().getFortId(); this.encounterId = proto.getLureInfo().getEncounterId(); this.pokemonId = proto.getLureInfo().getActivePokemonId(); this.expirationTimestampMs = proto.getLureInfo() .getLureExpiresTimestampMs(); this.latitude = proto.getLatitude(); this.longitude = proto.getLongitude(); + this.encounterKind = EncounterKind.DISK; + } + + /** + * Encounter pokemon + * + * @return the encounter result + */ + public EncounterResult encounterPokemon() throws LoginFailedException, RemoteServerException { + return encounterPokemonAsync().toBlocking(); } /** @@ -131,26 +160,41 @@ public CatchablePokemon(PokemonGo api, FortData proto) { * @return the encounter result */ public PokemonFuture encounterPokemonAsync() { - EncounterMessageOuterClass.EncounterMessage reqMsg = EncounterMessageOuterClass.EncounterMessage + if (encounterKind == EncounterKind.NORMAL) { + return encounterNormalPokemonAsync(); + } else if (encounterKind == EncounterKind.DISK) { + return encounterDiskPokemonAsync(); + } + + throw new IllegalStateException("Catchable pokemon missing encounter type"); + } + + /** + * Encounter pokemon encounter result. + * + * @return the encounter result + */ + public PokemonFuture encounterNormalPokemonAsync() { + EncounterMessage reqMsg = EncounterMessage .newBuilder().setEncounterId(getEncounterId()) .setPlayerLatitude(api.getLatitude()) .setPlayerLongitude(api.getLongitude()) .setSpawnPointId(getSpawnPointId()).build(); AsyncServerRequest serverRequest = new AsyncServerRequest( - RequestTypeOuterClass.RequestType.ENCOUNTER, reqMsg); + RequestType.ENCOUNTER, reqMsg); return new FutureWrapper(api.getRequestHandler() .sendAsyncServerRequests(serverRequest)) { @Override protected EncounterResult handle(ByteString result) throws RemoteServerException { - EncounterResponseOuterClass.EncounterResponse response; + EncounterResponse response; try { - response = EncounterResponseOuterClass.EncounterResponse + response = EncounterResponse .parseFrom(result); } catch (InvalidProtocolBufferException e) { throw new RemoteServerException(e); } encountered = response.getStatus() == EncounterResponse.Status.ENCOUNTER_SUCCESS; - return new EncounterResult(response); + return new NormalEncounterResult(response); } }; } @@ -162,11 +206,42 @@ protected EncounterResult handle(ByteString result) throws RemoteServerException * @throws LoginFailedException the login failed exception * @throws RemoteServerException the remote server exception */ - public EncounterResult encounterPokemon() throws LoginFailedException, + public EncounterResult encounterNormalPokemon() throws LoginFailedException, RemoteServerException { - return encounterPokemonAsync().toBlocking(); + return encounterNormalPokemonAsync().toBlocking(); + } + + + + /** + * Encounter pokemon + * + * @return the encounter result + */ + public PokemonFuture encounterDiskPokemonAsync() { + DiskEncounterMessage reqMsg = DiskEncounterMessage + .newBuilder().setEncounterId(getEncounterId()) + .setPlayerLatitude(api.getLatitude()) + .setPlayerLongitude(api.getLongitude()) + .setFortId(getSpawnPointId()).build(); + AsyncServerRequest serverRequest = new AsyncServerRequest(RequestType.DISK_ENCOUNTER, reqMsg); + return new FutureWrapper(api.getRequestHandler() + .sendAsyncServerRequests(serverRequest)) { + @Override + protected EncounterResult handle(ByteString result) throws RemoteServerException { + DiskEncounterResponse response; + try { + response = DiskEncounterResponse.parseFrom(result); + } catch (InvalidProtocolBufferException e) { + throw new RemoteServerException(e); + } + encountered = response.getResult() == DiskEncounterResponse.Result.SUCCESS; + return new DiskEncounterResult(response); + } + }; } + /** * Tries to catch a pokemon (will attempt to use a pokeball, if you have * none will use greatball etc) and uwill use a single razz berry if available. @@ -389,11 +464,12 @@ public PokemonFuture catchPokemonAsync(double normalizedHitPosition .setSpinModifier(spinModifier) .setPokeball(type.getBallType()).build(); AsyncServerRequest serverRequest = new AsyncServerRequest( - RequestTypeOuterClass.RequestType.CATCH_POKEMON, reqMsg); + RequestType.CATCH_POKEMON, reqMsg); return new FutureWrapper(api.getRequestHandler() .sendAsyncServerRequests(serverRequest)) { @Override protected CatchResult handle(ByteString result) throws RemoteServerException, LoginFailedException { + System.out.println("ASYNC CATCH CALL"); CatchPokemonResponse response; try { @@ -439,7 +515,7 @@ public PokemonFuture useItemAsync(ItemId item) { .build(); AsyncServerRequest serverRequest = new AsyncServerRequest( - RequestTypeOuterClass.RequestType.USE_ITEM_CAPTURE, reqMsg); + RequestType.USE_ITEM_CAPTURE, reqMsg); return new FutureWrapper(api.getRequestHandler() .sendAsyncServerRequests(serverRequest)) { @Override diff --git a/src/main/java/com/pokegoapi/api/map/pokemon/encounter/DiskEncounterResult.java b/src/main/java/com/pokegoapi/api/map/pokemon/encounter/DiskEncounterResult.java new file mode 100644 index 00000000..6ec4162d --- /dev/null +++ b/src/main/java/com/pokegoapi/api/map/pokemon/encounter/DiskEncounterResult.java @@ -0,0 +1,69 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.pokegoapi.api.map.pokemon.encounter; + + +import POGOProtos.Networking.Responses.DiskEncounterResponseOuterClass.DiskEncounterResponse; +import POGOProtos.Networking.Responses.EncounterResponseOuterClass; +import POGOProtos.Networking.Responses.EncounterResponseOuterClass.EncounterResponse; +import lombok.Getter; + +public class DiskEncounterResult implements EncounterResult { + @Getter + private DiskEncounterResponse response; + + public DiskEncounterResult(DiskEncounterResponse response) { + this.response = response; + } + + @Override + public boolean wasSuccessful() { + return response != null + && response.getResult() == DiskEncounterResponse.Result.SUCCESS; + } + + + //TODO: i have conveted the DiskEncounter response to maintain compatibility, if not required + //i think will be better to remove this method + + /** + * Return the status of the encounter + * + * @return status of results + */ + public EncounterResponse.Status getStatus() { + if (response == null) + return null; + switch (response.getResult()) { + case UNKNOWN: + return EncounterResponse.Status.ENCOUNTER_ERROR; + case SUCCESS: + return EncounterResponse.Status.ENCOUNTER_SUCCESS; + case NOT_AVAILABLE: + return EncounterResponse.Status.ENCOUNTER_NOT_FOUND; + case NOT_IN_RANGE: + return EncounterResponse.Status.ENCOUNTER_NOT_IN_RANGE; + case ENCOUNTER_ALREADY_FINISHED: + return EncounterResponse.Status.ENCOUNTER_ALREADY_HAPPENED; + case POKEMON_INVENTORY_FULL: + return EncounterResponse.Status.POKEMON_INVENTORY_FULL; + case UNRECOGNIZED: + return EncounterResponse.Status.UNRECOGNIZED; + default: + return EncounterResponse.Status.UNRECOGNIZED; + } + } +} diff --git a/src/main/java/com/pokegoapi/api/map/pokemon/encounter/EncounterResult.java b/src/main/java/com/pokegoapi/api/map/pokemon/encounter/EncounterResult.java new file mode 100644 index 00000000..1190a6a2 --- /dev/null +++ b/src/main/java/com/pokegoapi/api/map/pokemon/encounter/EncounterResult.java @@ -0,0 +1,29 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.pokegoapi.api.map.pokemon.encounter; + +import POGOProtos.Data.Capture.CaptureProbabilityOuterClass; +import POGOProtos.Map.Pokemon.WildPokemonOuterClass; +import POGOProtos.Networking.Responses.EncounterResponseOuterClass.EncounterResponse; + + + +public interface EncounterResult { + + boolean wasSuccessful(); + + EncounterResponse.Status getStatus(); +} \ No newline at end of file diff --git a/src/main/java/com/pokegoapi/api/map/pokemon/EncounterResult.java b/src/main/java/com/pokegoapi/api/map/pokemon/encounter/NormalEncounterResult.java similarity index 66% rename from src/main/java/com/pokegoapi/api/map/pokemon/EncounterResult.java rename to src/main/java/com/pokegoapi/api/map/pokemon/encounter/NormalEncounterResult.java index 0d4be261..dfd16aec 100644 --- a/src/main/java/com/pokegoapi/api/map/pokemon/EncounterResult.java +++ b/src/main/java/com/pokegoapi/api/map/pokemon/encounter/NormalEncounterResult.java @@ -13,42 +13,49 @@ * along with this program. If not, see . */ -package com.pokegoapi.api.map.pokemon; - -import POGOProtos.Data.Capture.CaptureProbabilityOuterClass; -import POGOProtos.Map.Pokemon.WildPokemonOuterClass; -import POGOProtos.Networking.Responses.EncounterResponseOuterClass.EncounterResponse; +package com.pokegoapi.api.map.pokemon.encounter; -public class EncounterResult { +import POGOProtos.Data.Capture.CaptureProbabilityOuterClass.CaptureProbability; +import POGOProtos.Map.Pokemon.WildPokemonOuterClass.WildPokemon; +import POGOProtos.Networking.Responses.EncounterResponseOuterClass.EncounterResponse; +public class NormalEncounterResult implements EncounterResult { private EncounterResponse response; - public EncounterResult(EncounterResponse response) { + public NormalEncounterResult(EncounterResponse response) { this.response = response; } + /** + * Return the status of the encounter + * + * @return status of results + */ public EncounterResponse.Status getStatus() { return response == null ? null : response.getStatus(); } public boolean wasSuccessful() { - return response != null && getStatus() != null && getStatus().equals(EncounterResponse.Status.ENCOUNTER_SUCCESS); + return response != null + && getStatus() != null && getStatus().equals(EncounterResponse.Status.ENCOUNTER_SUCCESS); } public EncounterResponse.Background getBackground() { return response.getBackground(); } - public CaptureProbabilityOuterClass.CaptureProbability getCaptureProbability() { + public CaptureProbability getCaptureProbability() { return response.getCaptureProbability(); } - public WildPokemonOuterClass.WildPokemon getWildPokemon() { + public WildPokemon getWildPokemon() { return response.getWildPokemon(); } public EncounterResponse toPrimitive() { return response; } -} + + +} \ No newline at end of file diff --git a/src/main/java/com/pokegoapi/auth/PtcCredentialProvider.java b/src/main/java/com/pokegoapi/auth/PtcCredentialProvider.java index ecea79c5..8733ce83 100644 --- a/src/main/java/com/pokegoapi/auth/PtcCredentialProvider.java +++ b/src/main/java/com/pokegoapi/auth/PtcCredentialProvider.java @@ -237,7 +237,7 @@ private void login(String username, String password) throws LoginFailedException this.expiresTimestamp = time.currentTimeMillis() + (Integer.valueOf(params[1].split("=")[1]) * 1000 - REFRESH_TOKEN_BUFFER_TIME); } catch (Exception e) { - throw new LoginFailedException("Failed to fetch token"); + throw new LoginFailedException("Failed to fetch token, body:" + body); } } diff --git a/src/main/java/com/pokegoapi/examples/CatchPokemonAtAreaExample.java b/src/main/java/com/pokegoapi/examples/CatchPokemonAtAreaExample.java index 293e518c..3e768509 100644 --- a/src/main/java/com/pokegoapi/examples/CatchPokemonAtAreaExample.java +++ b/src/main/java/com/pokegoapi/examples/CatchPokemonAtAreaExample.java @@ -35,7 +35,7 @@ import com.pokegoapi.api.PokemonGo; import com.pokegoapi.api.map.pokemon.CatchResult; import com.pokegoapi.api.map.pokemon.CatchablePokemon; -import com.pokegoapi.api.map.pokemon.EncounterResult; +import com.pokegoapi.api.map.pokemon.encounter.EncounterResult; import com.pokegoapi.auth.PtcCredentialProvider; import com.pokegoapi.exceptions.LoginFailedException; import com.pokegoapi.exceptions.NoSuchItemException; diff --git a/src/main/java/com/pokegoapi/main/RequestHandler.java b/src/main/java/com/pokegoapi/main/RequestHandler.java index 0f333e3b..3ecedb57 100644 --- a/src/main/java/com/pokegoapi/main/RequestHandler.java +++ b/src/main/java/com/pokegoapi/main/RequestHandler.java @@ -213,7 +213,7 @@ private AuthTicketOuterClass.AuthTicket internalSendServerRequests(AuthTicketOut } if (responseEnvelop.getStatusCode() == 102) { - throw new LoginFailedException(String.format("Error %s in API Url %s", + throw new LoginFailedException(String.format("Invalud Auth status code recieved, token not refreshed?", responseEnvelop.getApiUrl(), responseEnvelop.getError())); } else if (responseEnvelop.getStatusCode() == 53) { // 53 means that the api_endpoint was not correctly set, should be at this point, though, so redo the request diff --git a/src/main/java/com/pokegoapi/util/DummyFuture.java b/src/main/java/com/pokegoapi/util/DummyFuture.java deleted file mode 100644 index 7ade78bd..00000000 --- a/src/main/java/com/pokegoapi/util/DummyFuture.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.pokegoapi.util; - -import com.google.protobuf.InvalidProtocolBufferException; -import com.pokegoapi.exceptions.AsyncPokemonGoException; -import com.pokegoapi.exceptions.LoginFailedException; -import com.pokegoapi.exceptions.RemoteServerException; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -public class DummyFuture implements PokemonFuture { - - - protected final R result; - - public DummyFuture(R result) { - this.result = result; - } - - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - return false; - } - - @Override - public boolean isCancelled() { - return false; - } - - @Override - public boolean isDone() { - return true; - } - - @Override - public R get() throws InterruptedException, ExecutionException { - R result = getResult(1, TimeUnit.MINUTES); - while (result == null) { - result = getResult(1, TimeUnit.MINUTES); - } - return result; - } - - @Override - public R get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - R result = getResult(timeout, unit); - if (result == null) { - throw new TimeoutException("No result found"); - } - return result; - } - - protected R getResult(long timeouut, TimeUnit timeUnit) throws InterruptedException, ExecutionException { - return result; - } - - - /** - * Convert a future to its result - * - * @return The result or an unwrapped exception - * @throws RemoteServerException the remote server exception - * @throws LoginFailedException the login failed exception - */ - public R toBlocking() throws LoginFailedException, RemoteServerException { - return DummyFuture.toBlocking(this); - } - - /** - * Convert a future to its result - * - * @param future The future - * @param Result type - * @return The result or an unwrapped exception - * @throws RemoteServerException the remote server exception - * @throws LoginFailedException the login failed exception - */ - public static N toBlocking(Future future) throws LoginFailedException, RemoteServerException { - try { - return future.get(); - } catch (InterruptedException e) { - throw new AsyncPokemonGoException("Shutdown received", e); - } catch (ExecutionException e) { - if (e.getCause() instanceof LoginFailedException) { - throw (LoginFailedException) e.getCause(); - } - if (e.getCause() instanceof RemoteServerException) { - throw (RemoteServerException) e.getCause(); - } - if (e.getCause() instanceof InvalidProtocolBufferException) { - throw new RemoteServerException(e.getCause().getMessage(), e.getCause()); - } - throw new AsyncPokemonGoException("Unknown exception occurred. ", e); - } - } - - -} diff --git a/src/main/java/com/pokegoapi/util/FutureWrapper.java b/src/main/java/com/pokegoapi/util/FutureWrapper.java index ab502dc7..043406b3 100644 --- a/src/main/java/com/pokegoapi/util/FutureWrapper.java +++ b/src/main/java/com/pokegoapi/util/FutureWrapper.java @@ -145,5 +145,9 @@ public boolean isDone() { return true; } + @Override + protected R getResult(long timeouut, TimeUnit timeUnit) throws InterruptedException, ExecutionException { + return result; + } } } diff --git a/src/main/java/com/pokegoapi/util/MapUtil.java b/src/main/java/com/pokegoapi/util/MapUtil.java index d795017c..20384a09 100644 --- a/src/main/java/com/pokegoapi/util/MapUtil.java +++ b/src/main/java/com/pokegoapi/util/MapUtil.java @@ -75,11 +75,12 @@ public static double distFrom(double lat1, double lng1, double lat2, double lng2 double earthRadius = 6371000; double lat = Math.toRadians(lat2 - lat1); double lng = Math.toRadians(lng2 - lng1); - double a = Math.sin(lat / 2) * Math.sin(lat / 2) + double haversine = Math.sin(lat / 2) * Math.sin(lat / 2) + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.sin(lng / 2) * Math.sin(lng / 2); - return earthRadius * (2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))); + + return earthRadius * (2 * Math.atan2(Math.sqrt(haversine), Math.sqrt(1 - haversine))); } /**