Skip to content
This repository was archived by the owner on Aug 17, 2020. It is now read-only.

Commit 0618a0a

Browse files
author
Rover656
authored
Merge pull request #3 from WallyCZ/captcha
Changes in API to make work check challenge correctly + Captcha tested and verified it works
2 parents 2b8aa3a + b0da2b6 commit 0618a0a

File tree

9 files changed

+426
-69
lines changed

9 files changed

+426
-69
lines changed

PokemonGo-UWP/Utils/GameClient.cs

Lines changed: 76 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,31 @@ public static AccessToken LoadAccessToken()
354354
return tokenString == null ? null : JsonConvert.DeserializeObject<AccessToken>(SettingsService.Instance.AccessTokenString);
355355
}
356356

357+
358+
/// <summary>
359+
/// Creates and initializes API client
360+
/// </summary>
361+
private static void CreateClient()
362+
{
363+
//Unregister old handlers
364+
if (_client != null)
365+
{
366+
_client.CheckChallengeReceived -= _client_CheckChallengeReceived;
367+
}
368+
369+
_client = new Client(_clientSettings, null, DeviceInfos.Current);
370+
371+
//Register EventHandlers
372+
_client.CheckChallengeReceived += _client_CheckChallengeReceived;
373+
374+
var apiFailureStrategy = new ApiFailureStrategy(_client);
375+
_client.ApiFailure = apiFailureStrategy;
376+
// Register to AccessTokenChanged
377+
apiFailureStrategy.OnAccessTokenUpdated += (s, e) => SaveAccessToken();
378+
379+
}
380+
381+
357382
/// <summary>
358383
/// Sets things up if we didn't come from the login page
359384
/// </summary>
@@ -374,12 +399,8 @@ public static async Task InitializeClient()
374399
GooglePassword = SettingsService.Instance.LastLoginService == AuthType.Google ? credentials.Password : null,
375400
};
376401

377-
_client = new Client(_clientSettings, null, DeviceInfos.Current) {AccessToken = LoadAccessToken()};
378-
var apiFailureStrategy = new ApiFailureStrategy(_client);
379-
_client.ApiFailure = apiFailureStrategy;
380-
// Register to AccessTokenChanged
381-
apiFailureStrategy.OnAccessTokenUpdated += (s, e) => SaveAccessToken();
382-
apiFailureStrategy.OnFailureToggleUpdateTimer += ToggleUpdateTimer;
402+
CreateClient();
403+
383404
try
384405
{
385406
await _client.Login.DoLogin();
@@ -413,11 +434,9 @@ public static async Task<bool> DoPtcLogin(string username, string password)
413434
PtcPassword = password,
414435
AuthType = AuthType.Ptc
415436
};
416-
_client = new Client(_clientSettings, null, DeviceInfos.Current);
417-
var apiFailureStrategy = new ApiFailureStrategy(_client);
418-
_client.ApiFailure = apiFailureStrategy;
419-
// Register to AccessTokenChanged
420-
apiFailureStrategy.OnAccessTokenUpdated += (s, e) => SaveAccessToken();
437+
438+
CreateClient();
439+
421440
// Get PTC token
422441
await _client.Login.DoLogin();
423442
// Update current token even if it's null and clear the token for the other identity provide
@@ -431,6 +450,7 @@ public static async Task<bool> DoPtcLogin(string username, string password)
431450
return true;
432451
}
433452

453+
434454
/// <summary>
435455
/// Starts a Google session for the given user
436456
/// </summary>
@@ -446,11 +466,8 @@ public static async Task<bool> DoGoogleLogin(string email, string password)
446466
AuthType = AuthType.Google
447467
};
448468

449-
_client = new Client(_clientSettings, null, DeviceInfos.Current);
450-
var apiFailureStrategy = new ApiFailureStrategy(_client);
451-
_client.ApiFailure = apiFailureStrategy;
452-
// Register to AccessTokenChanged
453-
apiFailureStrategy.OnAccessTokenUpdated += (s, e) => SaveAccessToken();
469+
CreateClient();
470+
454471
// Get Google token
455472
await _client.Login.DoLogin();
456473
// Update current token even if it's null and clear the token for the other identity provide
@@ -551,7 +568,30 @@ public static async Task InitializeDataUpdate()
551568
Busy.SetBusy(false);
552569
}
553570

554-
private static async void LocationHelperPropertyChanged(object sender, PropertyChangedEventArgs e)
571+
private static async void _client_CheckChallengeReceived(object sender, CheckChallengeResponse e)
572+
{
573+
574+
if (e.ShowChallenge && !String.IsNullOrWhiteSpace(e.ChallengeUrl) && e.ChallengeUrl.Length > 5)
575+
{
576+
// Captcha is shown in checkChallengeResponse.ChallengeUrl
577+
Logger.Write($"ChallengeURL: {e.ChallengeUrl}");
578+
// breakpoint here to manually resolve Captcha in a browser
579+
// after that set token to str variable from browser (see screenshot)
580+
Logger.Write("Pause");
581+
582+
//GOTO THE REQUIRED PAGE
583+
if (BootStrapper.Current.NavigationService.CurrentPageType != typeof(ChallengePage))
584+
{
585+
await DispatcherHelper.RunInDispatcherAndAwait(() =>
586+
{
587+
// We are not in UI thread probably, so run this via dispatcher
588+
BootStrapper.Current.NavigationService.Navigate(typeof(ChallengePage), e.ChallengeUrl);
589+
});
590+
}
591+
}
592+
593+
}
594+
private static async void LocationHelperPropertyChanged(object sender, PropertyChangedEventArgs e)
555595
{
556596
if(e.PropertyName==nameof(LocationServiceHelper.Instance.Geoposition))
557597
{
@@ -628,25 +668,8 @@ private static async Task UpdateMapObjects()
628668
LuredPokemons.UpdateByIndexWith(newLuredPokemon, x => x);
629669
Logger.Write("Finished updating map objects");
630670

631-
// check if Captcha pending
632-
var checkChallengeResponse = await CheckChallenge();
633-
//var token = "";
634-
if (checkChallengeResponse.ShowChallenge)
635-
{
636-
// Captcha is shown in checkChallengeResponse.ChallengeUrl
637-
Logger.Write($"ChallengeURL: {checkChallengeResponse.ChallengeUrl}");
638-
// breakpoint here to manually resolve Captcha in a browser
639-
// after that set token to str variable from browser (see screenshot)
640-
Logger.Write($"Pause");
641-
642-
//GOTO THE REQUIRED PAGE
643-
BootStrapper.Current.NavigationService.Navigate(typeof(ChallengePage), checkChallengeResponse.ChallengeUrl);
644-
645-
//await VerifyChallenge(token);
646-
}
647-
648671
// Update Hatched Eggs
649-
var hatchedEggResponse = mapObjects.Item2;
672+
var hatchedEggResponse = mapObjects.Item3;
650673
if (hatchedEggResponse.Success)
651674
{
652675
//OnEggHatched?.Invoke(null, hatchedEggResponse);
@@ -693,22 +716,12 @@ private static async
693716
Task
694717
<
695718
Tuple
696-
<GetMapObjectsResponse, GetHatchedEggsResponse, GetInventoryResponse, CheckAwardedBadgesResponse,
719+
<GetMapObjectsResponse, CheckChallengeResponse, GetHatchedEggsResponse, GetInventoryResponse, CheckAwardedBadgesResponse,
697720
DownloadSettingsResponse>> GetMapObjects(Geoposition geoposition)
698721
{
699722
_lastGeopositionMapObjectsRequest = geoposition;
700723
return await _client.Map.GetMapObjects();
701724
}
702-
703-
private static async Task <CheckChallengeResponse> CheckChallenge()
704-
{
705-
return await _client.Misc.CheckChallenge();
706-
}
707-
708-
private static async Task <VerifyChallengeResponse> VerifyChallenge(string token)
709-
{
710-
return await _client.Misc.VerifyChallenge(token);
711-
}
712725

713726
#endregion
714727

@@ -1118,6 +1131,23 @@ public static EggIncubator GetIncubatorFromEgg(PokemonData egg)
11181131
return IncubatorsInventory.FirstOrDefault(item => item.Id == null ? false : item.Id.Equals(egg.EggIncubatorId));
11191132
}
11201133

1134+
#endregion
1135+
1136+
1137+
#region Misc
1138+
1139+
1140+
/// <summary>
1141+
/// Verifies challenge
1142+
/// </summary>
1143+
/// <param name="token"></param>
1144+
/// <returns></returns>
1145+
public static async Task<VerifyChallengeResponse> VerifyChallenge(string token)
1146+
{
1147+
return await _client.Misc.VerifyChallenge(token);
1148+
}
1149+
1150+
11211151
#endregion
11221152

11231153
#endregion

PokemonGo-UWP/Views/ChallengePage.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
mc:Ignorable="d">
99

1010
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
11-
<WebView Name="ChallengePanel" LoadCompleted="ChallengePanel_LoadCompleted"/>
11+
<WebView Name="ChallengePanel" LoadCompleted="ChallengePanel_LoadCompleted" UnsupportedUriSchemeIdentified="ChallengePanel_UnsupportedUriSchemeIdentified"/>
1212
</Grid>
1313
</Page>

PokemonGo-UWP/Views/ChallengePage.xaml.cs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using Newtonsoft.Json;
2+
using Newtonsoft.Json.Linq;
13
using POGOProtos.Networking.Responses;
24
using PokemonGo.RocketAPI;
35
using PokemonGo_UWP.Utils;
@@ -28,41 +30,56 @@ namespace PokemonGo_UWP.Views
2830
public sealed partial class ChallengePage : Page
2931
{
3032
public string ChallengeUri;
31-
private static Client _client;
3233
public ChallengePage()
3334
{
3435
this.InitializeComponent();
3536
}
3637
protected override void OnNavigatedTo(NavigationEventArgs e)
3738
{
3839
base.OnNavigatedTo(e);
39-
ChallengeUri = e.Parameter.ToString();
40+
ChallengeUri = ((JObject)JsonConvert.DeserializeObject((string)e.Parameter)).Last
41+
.ToObject<string>();
42+
43+
if (ChallengeUri.Length > 0 && ChallengeUri[0] == '"')
44+
ChallengeUri = ChallengeUri.Substring(1);
45+
46+
if (ChallengeUri.Length > 0 && ChallengeUri[ChallengeUri.Length-1] == '"')
47+
ChallengeUri = ChallengeUri.Substring(0, ChallengeUri.Length - 1);
48+
4049
ChallengePanel.Navigate(new Uri(ChallengeUri));
50+
Busy.SetBusy(false);
4151
}
4252

4353
private void ChallengePanel_LoadCompleted(object sender, NavigationEventArgs e)
4454
{
4555
string url = e.Uri.ToString();
46-
if (url.StartsWith("unity:"))
47-
{
48-
string token = url.Substring("unity:".Length);
49-
Verify(token);
50-
}
51-
else
52-
{
53-
//Error, no token!
54-
}
56+
if (url.StartsWith("unity:"))
57+
{
58+
string token = url.Substring("unity:".Length);
59+
Verify(token);
60+
}
61+
else
62+
{
63+
//Error, no token!
5564
}
5665
}
5766
private async void Verify(string token)
5867
{
59-
await VerifyChallenge(token);
68+
await GameClient.VerifyChallenge(token);
6069
//BootStrapper.Current.NavigationService.Navigate(typeof(GameMapPage));
6170
if (this.Frame != null && this.Frame.CanGoBack) this.Frame.GoBack();
6271
}
63-
private static async Task <VerifyChallengeResponse> VerifyChallenge(string token)
72+
73+
private void ChallengePanel_UnsupportedUriSchemeIdentified(WebView sender, WebViewUnsupportedUriSchemeIdentifiedEventArgs args)
6474
{
65-
return await _client.Misc.VerifyChallenge(token);
75+
76+
string url = args.Uri.ToString();
77+
if (url.StartsWith("unity:"))
78+
{
79+
string token = url.Substring("unity:".Length);
80+
Verify(token);
81+
args.Handled = true;
82+
}
6683
}
6784
}
6885
}

PokemonGoAPI/Client.cs

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313
using PokemonGo.RocketAPI.Exceptions;
1414
using System.Diagnostics;
1515
using System;
16+
using Google.Protobuf.Collections;
1617

1718
namespace PokemonGo.RocketAPI
1819
{
19-
public class Client : HttpClient
20+
public partial class Client : HttpClient
2021
{
2122
private static readonly HttpClientHandler Handler = new HttpClientHandler
2223
{
@@ -174,7 +175,7 @@ public async Task<ResponseEnvelope> PostProto<TRequest>(string url, RequestEnvel
174175

175176
//Encode payload and put in envelop, then send
176177
var data = requestEnvelope.ToByteString();
177-
var result = await PostAsync(url, new ByteArrayContent(data.ToByteArray()));
178+
var result = await PostAsync(url, new ByteArrayContent(data.ToByteArray())).ConfigureAwait(false);
178179

179180
//Decode message
180181
var responseData = await result.Content.ReadAsByteArrayAsync();
@@ -187,6 +188,50 @@ public async Task<ResponseEnvelope> PostProto<TRequest>(string url, RequestEnvel
187188

188189
#endregion
189190

190-
}
191+
#region API 2.0 bridge
192+
193+
// For smoother migration to 2.0
194+
195+
196+
// Conversion from obsolete Tuple
197+
internal bool ProcessMessages<T1, T2, T3, T4, T5, T6>(Tuple<T1, T2, T3, T4, T5, T6> tuple)
198+
where T1 : class, IMessage, new()
199+
where T2 : class, IMessage, new()
200+
where T3 : class, IMessage, new()
201+
where T4 : class, IMessage, new()
202+
where T5 : class, IMessage, new()
203+
where T6 : class, IMessage, new()
204+
{
205+
IMessage[] msgs = new IMessage[] { tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4, tuple.Item5, tuple.Item6 };
206+
return ProcessMessages(msgs);
207+
}
208+
209+
// Conversion from obsolete Tuple
210+
internal bool ProcessMessages<T1, T2>(Tuple<T1, T2> tuple)
211+
where T1 : class, IMessage, new()
212+
where T2 : class, IMessage, new()
213+
{
214+
IMessage[] msgs = new IMessage[] { tuple.Item1, tuple.Item2};
215+
return ProcessMessages(msgs);
216+
}
217+
218+
internal bool ProcessMessages(RepeatedField<ByteString> responses, params Type[] responseTypes)
219+
{
220+
IMessage[] msgs = new IMessage[responses.Count];
221+
222+
for (var i = 0; i < responseTypes.Length; i++)
223+
{
224+
msgs[i] = Activator.CreateInstance(responseTypes[i]) as IMessage;
225+
226+
var payload = responses[i];
227+
msgs[i].MergeFrom(payload);
228+
}
229+
230+
return ProcessMessages(msgs);
231+
}
232+
233+
#endregion
234+
235+
}
191236

192237
}

PokemonGoAPI/PokemonGoAPI.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@
155155
<Compile Include="Login\PtcAuthenticationTicketResponse.cs" />
156156
<Compile Include="Login\PtcLogin.cs" />
157157
<Compile Include="Login\PtcLoginParameters.cs" />
158+
<Compile Include="PokemonGoApiClient.Events.Generated.cs" />
158159
<Compile Include="Proto\Data\BuddyPokemon.cs" />
159160
<Compile Include="Proto\Data\Logs\BuddyPokemonLogEntry.cs" />
160161
<Compile Include="Proto\Networking\Envelopes\Signature.cs" />

0 commit comments

Comments
 (0)