1919import POGOProtos .Networking .Envelopes .RequestEnvelopeOuterClass .RequestEnvelope .AuthInfo ;
2020import POGOProtos .Networking .Envelopes .SignatureOuterClass ;
2121import POGOProtos .Networking .Requests .Messages .CheckChallenge .CheckChallengeMessage ;
22+ import POGOProtos .Networking .Requests .Messages .DownloadItemTemplatesMessageOuterClass .DownloadItemTemplatesMessage ;
23+ import POGOProtos .Networking .Requests .Messages .LevelUpRewardsMessageOuterClass .LevelUpRewardsMessage ;
2224import POGOProtos .Networking .Requests .Messages .VerifyChallenge .VerifyChallengeMessage ;
23- import POGOProtos .Networking .Requests .RequestTypeOuterClass ;
2425import POGOProtos .Networking .Requests .RequestTypeOuterClass .RequestType ;
2526import POGOProtos .Networking .Responses .CheckChallengeResponseOuterClass .CheckChallengeResponse ;
27+ import POGOProtos .Networking .Responses .DownloadRemoteConfigVersionResponseOuterClass .DownloadRemoteConfigVersionResponse ;
28+ import POGOProtos .Networking .Responses .LevelUpRewardsResponseOuterClass .LevelUpRewardsResponse ;
29+ import POGOProtos .Networking .Responses .LevelUpRewardsResponseOuterClass .LevelUpRewardsResponse .Result ;
2630import POGOProtos .Networking .Responses .VerifyChallengeResponseOuterClass .VerifyChallengeResponse ;
2731import com .google .protobuf .ByteString ;
2832import com .google .protobuf .InvalidProtocolBufferException ;
4347import com .pokegoapi .exceptions .RemoteServerException ;
4448import com .pokegoapi .main .AsyncServerRequest ;
4549import com .pokegoapi .main .CommonRequests ;
50+ import com .pokegoapi .main .Heartbeat ;
51+ import com .pokegoapi .main .PokemonMeta ;
4652import com .pokegoapi .main .RequestHandler ;
4753import com .pokegoapi .main .ServerRequest ;
4854import com .pokegoapi .util .AsyncHelper ;
5359import lombok .Setter ;
5460import okhttp3 .OkHttpClient ;
5561
62+ import java .io .IOException ;
5663import java .lang .reflect .Method ;
5764import java .util .ArrayList ;
5865import java .util .Collections ;
@@ -108,6 +115,7 @@ public class PokemonGo {
108115 private boolean hasChallenge ;
109116 @ Getter
110117 private String challengeURL ;
118+ private final Object challengeLock = new Object ();
111119
112120 @ Getter
113121 private List <Listener > listeners = Collections .synchronizedList (new ArrayList <Listener >());
@@ -117,6 +125,9 @@ public class PokemonGo {
117125 @ Getter
118126 private boolean loggingIn ;
119127
128+ @ Getter
129+ private Heartbeat heartbeat = new Heartbeat (this );
130+
120131 /**
121132 * Instantiates a new Pokemon go.
122133 *
@@ -190,25 +201,58 @@ public void login(CredentialProvider credentialProvider)
190201 inventories = new Inventories (this );
191202 settings = new Settings (this );
192203 playerProfile = new PlayerProfile (this );
193- playerProfile .updateProfile ();
194204
195205 initialize ();
196-
197- this .loggingIn = false ;
198206 }
199207
200208 private void initialize () throws RemoteServerException , CaptchaActiveException , LoginFailedException {
201- fireRequestBlock (new ServerRequest (RequestType .DOWNLOAD_REMOTE_CONFIG_VERSION ,
202- CommonRequests .getDownloadRemoteConfigVersionMessageRequest ()));
209+ playerProfile .updateProfile ();
210+
211+ ServerRequest downloadConfigRequest = new ServerRequest (RequestType .DOWNLOAD_REMOTE_CONFIG_VERSION ,
212+ CommonRequests .getDownloadRemoteConfigVersionMessageRequest ());
213+ fireRequestBlock (downloadConfigRequest , RequestType .GET_BUDDY_WALKED );
214+ getAssetDigest ();
215+
216+ try {
217+ ByteString configVersionData = downloadConfigRequest .getData ();
218+ if (PokemonMeta .checkVersion (DownloadRemoteConfigVersionResponse .parseFrom (configVersionData ))) {
219+ DownloadItemTemplatesMessage message = CommonRequests .getDownloadItemTemplatesRequest ();
220+ ServerRequest templatesRequest = new ServerRequest (RequestType .DOWNLOAD_ITEM_TEMPLATES , message )
221+ .withCommons ();
222+ fireRequestBlock (templatesRequest );
223+ PokemonMeta .update (templatesRequest .getData (), true );
224+ }
225+ } catch (InvalidProtocolBufferException e ) {
226+ throw new RemoteServerException (e );
227+ } catch (IOException e ) {
228+ throw new RuntimeException (e );
229+ }
203230
204- fireRequestBlockTwo ();
231+ playerProfile .getProfile ();
232+
233+ try {
234+ LevelUpRewardsMessage rewardsMessage = LevelUpRewardsMessage .newBuilder ()
235+ .setLevel (playerProfile .getLevel ())
236+ .build ();
237+ ServerRequest levelUpRewards = new ServerRequest (RequestType .LEVEL_UP_REWARDS , rewardsMessage );
238+ fireRequestBlock (levelUpRewards );
239+ ByteString levelUpData = levelUpRewards .getData ();
240+ LevelUpRewardsResponse levelUpRewardsResponse = LevelUpRewardsResponse .parseFrom (levelUpData );
241+ if (levelUpRewardsResponse .getResult () == Result .SUCCESS ) {
242+ inventories .getItemBag ().addAwardedItems (levelUpRewardsResponse );
243+ }
244+ } catch (InvalidProtocolBufferException e ) {
245+ throw new RemoteServerException (e );
246+ }
205247
206248 List <LoginListener > loginListeners = getListeners (LoginListener .class );
207249
208250 for (LoginListener listener : loginListeners ) {
209251 listener .onLogin (this );
210252 }
211253
254+ this .loggingIn = false ;
255+
212256 // From now one we will start to check our accounts is ready to fire requests.
213257 // Actually, we can receive valid responses even with this first check,
214258 // that mark the tutorial state into LEGAL_SCREEN.
@@ -228,7 +272,8 @@ private void initialize() throws RemoteServerException, CaptchaActiveException,
228272 playerProfile .encounterTutorialComplete ();
229273 }
230274
231- if (!tutorialStates .contains (TutorialState .NAME_SELECTION )) {
275+ int remainingCodenameClaims = getPlayerProfile ().getPlayerData ().getRemainingCodenameClaims ();
276+ if (!tutorialStates .contains (TutorialState .NAME_SELECTION ) && remainingCodenameClaims > 0 ) {
232277 playerProfile .claimCodeName ();
233278 }
234279
@@ -241,13 +286,19 @@ private void initialize() throws RemoteServerException, CaptchaActiveException,
241286 * Fire requests block.
242287 *
243288 * @param request server request
289+ * @param exclude the commmon requests to exclude
244290 * @throws LoginFailedException When login fails
245291 * @throws RemoteServerException When server fails
246292 * @throws CaptchaActiveException if a captcha is active and the message can't be sent
247293 */
248- private void fireRequestBlock (ServerRequest request )
294+ private void fireRequestBlock (ServerRequest request , RequestType ... exclude )
249295 throws RemoteServerException , CaptchaActiveException , LoginFailedException {
250- getRequestHandler ().sendServerRequests (request .withCommons ());
296+ getRequestHandler ().sendServerRequests (request .withCommons ().exclude (exclude ));
297+ try {
298+ awaitChallenge ();
299+ } catch (InterruptedException e ) {
300+ throw new LoginFailedException (e );
301+ }
251302 }
252303
253304 /**
@@ -257,9 +308,9 @@ private void fireRequestBlock(ServerRequest request)
257308 * @throws RemoteServerException When server fails
258309 * @throws CaptchaActiveException if a captcha is active and the message can't be sent
259310 */
260- public void fireRequestBlockTwo () throws RemoteServerException , CaptchaActiveException , LoginFailedException {
261- fireRequestBlock (new ServerRequest (RequestTypeOuterClass . RequestType .GET_ASSET_DIGEST ,
262- CommonRequests .getGetAssetDigestMessageRequest ()));
311+ public void getAssetDigest () throws RemoteServerException , CaptchaActiveException , LoginFailedException {
312+ fireRequestBlock (new ServerRequest (RequestType .GET_ASSET_DIGEST ,
313+ CommonRequests .getGetAssetDigestMessageRequest ()). exclude ( RequestType . GET_BUDDY_WALKED ) );
263314 }
264315
265316 /**
@@ -313,13 +364,13 @@ public void setLocation(double latitude, double longitude, double altitude) {
313364 * @param accuracy the accuracy of this location
314365 */
315366 public void setLocation (double latitude , double longitude , double altitude , double accuracy ) {
316- if (latitude != this .latitude || longitude != this .longitude ) {
317- getMap ().clearCache ();
318- }
319367 setLatitude (latitude );
320368 setLongitude (longitude );
321369 setAltitude (altitude );
322370 setAccuracy (accuracy );
371+ if (!heartbeat .active () && !Double .isNaN (latitude ) && !Double .isNaN (longitude )) {
372+ heartbeat .start ();
373+ }
323374 }
324375
325376 public long currentTimeMillis () {
@@ -418,6 +469,10 @@ public void updateChallenge(String url, boolean hasChallenge) {
418469 for (LoginListener listener : listeners ) {
419470 listener .onChallenge (this , url );
420471 }
472+ } else {
473+ synchronized (challengeLock ) {
474+ challengeLock .notifyAll ();
475+ }
421476 }
422477 }
423478
@@ -511,6 +566,9 @@ public boolean verifyChallenge(String token)
511566 hasChallenge = !response .getSuccess ();
512567 if (!hasChallenge ) {
513568 challengeURL = null ;
569+ synchronized (challengeLock ) {
570+ challengeLock .notifyAll ();
571+ }
514572 }
515573 return response .getSuccess ();
516574 }
@@ -545,4 +603,26 @@ public String checkChallenge()
545603 public Point getPoint () {
546604 return new Point (this .getLatitude (), this .getLongitude ());
547605 }
606+
607+ /**
608+ * Blocks this thread until the current challenge is solved
609+ *
610+ * @throws InterruptedException if this thread is interrupted while blocking
611+ */
612+ public void awaitChallenge () throws InterruptedException {
613+ if (hasChallenge ()) {
614+ synchronized (challengeLock ) {
615+ challengeLock .wait ();
616+ }
617+ }
618+ }
619+
620+ /**
621+ * Enqueues the given task
622+ *
623+ * @param task the task to enqueue
624+ */
625+ public void enqueueTask (Runnable task ) {
626+ heartbeat .enqueueTask (task );
627+ }
548628}
0 commit comments