diff --git a/POGOLib.Official/Constants.cs b/POGOLib.Official/Constants.cs index 867d41f5e..d95a4aa84 100644 --- a/POGOLib.Official/Constants.cs +++ b/POGOLib.Official/Constants.cs @@ -5,20 +5,18 @@ public static class Constants // API stuff public const string ApiUrl = "https://pgorelease.nianticlabs.com/plfe/rpc"; + public const string ApiUserAgent = "Niantic App"; public const string VersionUrl = "https://pgorelease.nianticlabs.com/plfe/version"; // Login stuff public const string LoginUrl = "https://sso.pokemon.com/sso/login?service=https%3A%2F%2Fsso.pokemon.com%2Fsso%2Foauth2.0%2FcallbackAuthorize"; - - public const string LoginUserAgent = "Niantic App"; + public const string LoginUserAgent = "pokemongo/1 CFNetwork/808.3 Darwin/16.3.0"; public const string LoginOauthUrl = "https://sso.pokemon.com/sso/oauth2.0/accessToken"; public const string GoogleAuthService = "audience:server:client_id:848232511240-7so421jotr2609rmqakceuu1luuq0ptb.apps.googleusercontent.com"; - public const string GoogleAuthApp = "com.nianticlabs.pokemongo"; public const string GoogleAuthClientSig = "321187995bc7cdc2b5fc91b11a96e2baa8602c62"; - } } \ No newline at end of file diff --git a/POGOLib.Official/Net/Authentication/Login.cs b/POGOLib.Official/Net/Authentication/Login.cs index 7ea1769cc..55f8577c0 100644 --- a/POGOLib.Official/Net/Authentication/Login.cs +++ b/POGOLib.Official/Net/Authentication/Login.cs @@ -4,7 +4,7 @@ using POGOLib.Official.Logging; using POGOLib.Official.LoginProviders; using POGOLib.Official.Net.Authentication.Data; -using static POGOProtos.Networking.Envelopes.Signature.Types; +using POGOLib.Official.Util.Device; namespace POGOLib.Official.Net.Authentication { @@ -20,16 +20,16 @@ public static class Login /// /// The initial latitude you will spawn at after logging into PokémonGo. /// The initial longitude you will spawn at after logging into PokémonGo. - /// The used by the , keep null if you want a randomly generated . + /// The used by the , keep null if you want a randomly generated . /// - public static Session GetSession(ILoginProvider loginProvider, AccessToken accessToken, double initialLatitude, double initialLongitude, DeviceInfo deviceInfo = null) + public static Session GetSession(ILoginProvider loginProvider, AccessToken accessToken, double initialLatitude, double initialLongitude, DeviceWrapper deviceWrapper = null) { if (accessToken.IsExpired) throw new Exception("AccessToken is expired."); Logger.Debug("Authenticated from cache."); - return new Session(loginProvider, accessToken, new GeoCoordinate(initialLatitude, initialLongitude), deviceInfo); + return new Session(loginProvider, accessToken, new GeoCoordinate(initialLatitude, initialLongitude), deviceWrapper); } /// @@ -38,11 +38,11 @@ public static Session GetSession(ILoginProvider loginProvider, AccessToken acces /// The OAuth provider you use to authenticate. /// The initial latitude you will spawn at after logging into PokémonGo. /// The initial longitude you will spawn at after logging into PokémonGo. - /// The used by the , keep null if you want a randomly generated . + /// The used by the , keep null if you want a randomly generated . /// - public static async Task GetSession(ILoginProvider loginProvider, double initialLatitude, double initialLongitude, DeviceInfo deviceInfo = null) + public static async Task GetSession(ILoginProvider loginProvider, double initialLatitude, double initialLongitude, DeviceWrapper deviceWrapper = null) { - return new Session(loginProvider, await loginProvider.GetAccessToken(), new GeoCoordinate(initialLatitude, initialLongitude), deviceInfo); + return new Session(loginProvider, await loginProvider.GetAccessToken(), new GeoCoordinate(initialLatitude, initialLongitude), deviceWrapper); } /// @@ -51,9 +51,9 @@ public static async Task GetSession(ILoginProvider loginProvider, doubl /// The OAuth provider you use to authenticate. /// The you want to re-use. /// The initial coordinate you will spawn at after logging into PokémonGo. - /// The used by the , keep null if you want a randomly generated . + /// The used by the , keep null if you want a randomly generated . /// - public static Session GetSession(ILoginProvider loginProvider, AccessToken accessToken, GeoCoordinate coordinate, DeviceInfo deviceInfo = null) + public static Session GetSession(ILoginProvider loginProvider, AccessToken accessToken, GeoCoordinate coordinate, DeviceWrapper deviceWrapper = null) { if (accessToken.IsExpired) { @@ -61,7 +61,7 @@ public static Session GetSession(ILoginProvider loginProvider, AccessToken acces } Logger.Debug("Authenticated from cache."); - return new Session(loginProvider, accessToken, coordinate, deviceInfo); + return new Session(loginProvider, accessToken, coordinate, deviceWrapper); } /// @@ -69,12 +69,11 @@ public static Session GetSession(ILoginProvider loginProvider, AccessToken acces /// /// The OAuth provider you use to authenticate. /// The initial coordinate you will spawn at after logging into PokémonGo. - /// The used by the , keep null if you want a randomly generated . + /// The used by the , keep null if you want a randomly generated . /// - public static async Task GetSession(ILoginProvider loginProvider, GeoCoordinate coordinate, DeviceInfo deviceInfo = null) + public static async Task GetSession(ILoginProvider loginProvider, GeoCoordinate coordinate, DeviceWrapper deviceWrapper = null) { - return new Session(loginProvider, await loginProvider.GetAccessToken(), coordinate, deviceInfo); + return new Session(loginProvider, await loginProvider.GetAccessToken(), coordinate, deviceWrapper); } - } } diff --git a/POGOLib.Official/Net/RpcClient.cs b/POGOLib.Official/Net/RpcClient.cs index f6b9f4e06..e07299de2 100644 --- a/POGOLib.Official/Net/RpcClient.cs +++ b/POGOLib.Official/Net/RpcClient.cs @@ -20,6 +20,7 @@ using POGOProtos.Networking.Platform; using POGOProtos.Networking.Platform.Requests; using POGOProtos.Networking.Platform.Responses; +using System.Diagnostics; namespace POGOLib.Official.Net { @@ -80,7 +81,7 @@ internal RpcClient(Session session) internal Platform GetPlatform() { - return _session.DeviceInfo.DeviceBrand == "Apple" ? Platform.Ios : Platform.Android; + return _session.Device.DeviceInfo.DeviceBrand == "Apple" ? Platform.Ios : Platform.Android; } private long PositiveRandom() @@ -116,20 +117,27 @@ internal async Task StartupAsync() { // Send GetPlayer to check if we're connected and authenticated GetPlayerResponse playerResponse; + + int loop = 0; + do { var response = await SendRemoteProcedureCallAsync(new[] { new Request { - RequestType = RequestType.GetPlayer + RequestType = RequestType.GetPlayer, + RequestMessage = new GetPlayerMessage + { + + }.ToByteString() }, new Request { RequestType = RequestType.CheckChallenge, RequestMessage = new CheckChallengeMessage { - DebugRequest = false + }.ToByteString() } }); @@ -138,7 +146,8 @@ internal async Task StartupAsync() { await Task.Delay(TimeSpan.FromMilliseconds(1000)); } - } while (!playerResponse.Success); + loop++; + } while (!playerResponse.Success && loop < 10); _session.Player.Data = playerResponse.PlayerData; diff --git a/POGOLib.Official/Net/RpcEncryption.cs b/POGOLib.Official/Net/RpcEncryption.cs index 592b7941d..58b545675 100644 --- a/POGOLib.Official/Net/RpcEncryption.cs +++ b/POGOLib.Official/Net/RpcEncryption.cs @@ -170,7 +170,7 @@ internal async Task GenerateSignatureAsync(RequestEnvelope requ Status = 3 } }, - DeviceInfo = _session.DeviceInfo, + DeviceInfo = _session.Device.DeviceInfo, LocationFix = { locationFixes }, ActivityStatus = new ActivityStatus { diff --git a/POGOLib.Official/Net/Session.cs b/POGOLib.Official/Net/Session.cs index d76e4521b..973b19300 100644 --- a/POGOLib.Official/Net/Session.cs +++ b/POGOLib.Official/Net/Session.cs @@ -13,8 +13,9 @@ using POGOLib.Official.Pokemon; using POGOLib.Official.Util.Device; using POGOLib.Official.Util.Hash; +using POGOProtos.Data; using POGOProtos.Settings; -using static POGOProtos.Networking.Envelopes.Signature.Types; +using System.Diagnostics; namespace POGOLib.Official.Net { @@ -44,7 +45,7 @@ public class Session : IDisposable // public IDataCache DataCache { get; set; } = new MemoryDataCache(); // public Templates Templates { get; private set; } - internal Session(ILoginProvider loginProvider, AccessToken accessToken, GeoCoordinate geoCoordinate, DeviceInfo deviceInfo = null) + internal Session(ILoginProvider loginProvider, AccessToken accessToken, GeoCoordinate geoCoordinate, DeviceWrapper deviceWrapper = null) { if (!ValidLoginProviders.Contains(loginProvider.ProviderId)) { @@ -52,15 +53,15 @@ internal Session(ILoginProvider loginProvider, AccessToken accessToken, GeoCoord } State = SessionState.Stopped; + Device = deviceWrapper ?? DeviceInfoUtil.GetRandomDevice(); HttpClient = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }); - HttpClient.DefaultRequestHeaders.UserAgent.TryParseAdd("Niantic App"); + HttpClient.DefaultRequestHeaders.UserAgent.TryParseAdd(Constants.ApiUserAgent); HttpClient.DefaultRequestHeaders.ExpectContinue = false; - DeviceInfo = deviceInfo ?? DeviceInfoUtil.GetRandomDevice(this); AccessToken = accessToken; LoginProvider = loginProvider; Player = new Player(this, geoCoordinate); @@ -89,14 +90,14 @@ private set internal Random Random { get; private set; } = new Random(); /// - /// Gets the of the . + /// Gets the used by . /// - internal HttpClient HttpClient { get; } + public DeviceWrapper Device { get; private set; } /// - /// Gets the used by . + /// Gets the of the . /// - public DeviceInfo DeviceInfo { get; private set; } + internal HttpClient HttpClient { get; } /// /// Gets the used to obtain an . @@ -198,15 +199,19 @@ public void Shutdown() /// public async Task CheckHasherVersion() { - var pogoVersionRaw = await HttpClient.GetStringAsync(Constants.VersionUrl); - pogoVersionRaw = pogoVersionRaw.Replace("\n", ""); - pogoVersionRaw = pogoVersionRaw.Replace("\u0006", ""); - - var pogoVersion = new Version(pogoVersionRaw); - var result = Configuration.Hasher.PokemonVersion.CompareTo(pogoVersion); - if (result < 0) + using (var checkHttpClient = new HttpClient()) { - throw new HashVersionMismatchException($"The version of the {nameof(Configuration.Hasher)} ({Configuration.Hasher.PokemonVersion}) does not match the minimal API version of PokemonGo ({pogoVersion})."); + checkHttpClient.DefaultRequestHeaders.UserAgent.TryParseAdd(Device.UserAgent); + + var clientVersionRaw = await checkHttpClient.GetByteArrayAsync(Constants.VersionUrl); + var clientVersion = ClientVersion.Parser.ParseFrom(clientVersionRaw); + + var pogoVersion = new Version(clientVersion.MinVersion); + var result = Configuration.Hasher.PokemonVersion.CompareTo(pogoVersion); + if (result < 0) + { + throw new HashVersionMismatchException($"The version of the {nameof(Configuration.Hasher)} ({Configuration.Hasher.PokemonVersion}) does not match the minimal API version of PokemonGo ({pogoVersion}). Set 'Configuration.IgnoreHashVersion' to true if you want to disable the version check."); + } } } diff --git a/POGOLib.Official/POGOLib.Official.csproj b/POGOLib.Official/POGOLib.Official.csproj index 804b184f5..481e1f27c 100644 --- a/POGOLib.Official/POGOLib.Official.csproj +++ b/POGOLib.Official/POGOLib.Official.csproj @@ -65,6 +65,7 @@ + diff --git a/POGOLib.Official/Util/Device/DeviceInfoUtil.cs b/POGOLib.Official/Util/Device/DeviceInfoUtil.cs index 3eabee246..a1bb39c65 100644 --- a/POGOLib.Official/Util/Device/DeviceInfoUtil.cs +++ b/POGOLib.Official/Util/Device/DeviceInfoUtil.cs @@ -1,11 +1,13 @@ -using POGOLib.Official.Extensions; -using POGOLib.Official.Net; +using System; +using POGOLib.Official.Extensions; using static POGOProtos.Networking.Envelopes.Signature.Types; namespace POGOLib.Official.Util.Device { public class DeviceInfoUtil { + private static readonly Random Random = new Random(); + private static readonly string[][] Devices = { new[] {"iPad3,1", "iPad", "J1AP"}, @@ -41,27 +43,69 @@ public class DeviceInfoUtil }; private static readonly string[] OsVersions = { - "8.1.1", "8.1.2", "8.1.3", "8.2", "8.3", - "8.4", "8.4.1", "9.0", "9.0.1", "9.0.2", - "9.1", "9.2", "9.2.1", "9.3", "9.3.1", - "9.3.2", "9.3.3", "9.3.4" + "8.1.1", + "8.1.2", + "8.1.3", + "8.2", + "8.3", + "8.4", + "8.4.1", + "9.0", + "9.0.1", + "9.0.2", + "9.1", + "9.2", + "9.2.1", + "9.3", +// "9.3.1", + "9.3.2", +// "9.3.3", +// "9.3.4" + }; + + private static readonly string[] OsUserAgentParts = { + "CFNetwork/711.1.16 Darwin/14.0.0", // 8.1.1 + "CFNetwork/711.1.16 Darwin/14.0.0", // 8.1.2 + "CFNetwork/711.1.16 Darwin/14.0.0", // 8.1.3 + "CFNetwork/711.2.23 Darwin/14.0.0", // 8.2 + "CFNetwork/711.3.18 Darwin/14.0.0", // 8.3 + "CFNetwork/711.4.6 Darwin/14.4.0", // 8.4 + "CFNetwork/711.4.6 Darwin/14.4.0", // 8.4.1 + "CFNetwork/758.0.2 Darwin/15.0.0", // 9.0 + "CFNetwork/758.0.2 Darwin/15.0.0", // 9.0.1 + "CFNetwork/758.0.2 Darwin/15.0.0", // 9.0.2 + "CFNetwork/758.1.6 Darwin/15.0.0", // 9.1 + "CFNetwork/758.2.8 Darwin/15.0.0", // 9.2 + "CFNetwork/758.2.8 Darwin/15.0.0", // 9.2.1 + "CFNetwork/758.3.15 Darwin/15.4.0", // 9.3 +// "9.3.1", // 9.3.1 + "CFNetwork/758.4.3 Darwin/15.5.0", // 9.3.2 +// "9.3.3", // 9.3.3 +// "9.3.4" // 9.3.4 }; - public static DeviceInfo GetRandomDevice(Session session) + public static DeviceWrapper GetRandomDevice() { - var device = Devices[session.Random.Next(Devices.Length)]; - var firmwareType = OsVersions[session.Random.Next(OsVersions.Length)]; + var device = Devices[Random.Next(Devices.Length)]; + + var osId = Random.Next(OsVersions.Length); + var firmwareType = OsVersions[osId]; + var firmwareUserAgentPart = OsUserAgentParts[osId]; - return new DeviceInfo + return new DeviceWrapper { - DeviceId = session.Random.NextHexNumber(32).ToLower(), - DeviceBrand = "Apple", - DeviceModelBoot = device[0], - DeviceModel = device[1], - HardwareModel = device[2], - HardwareManufacturer = "Apple", - FirmwareBrand = "iPhone OS", - FirmwareType = firmwareType, + UserAgent = $"pokemongo/1 {firmwareUserAgentPart}", + DeviceInfo = new DeviceInfo + { + DeviceId = Random.NextHexNumber(32).ToLower(), + DeviceBrand = "Apple", + DeviceModelBoot = device[0], + DeviceModel = device[1], + HardwareModel = device[2], + HardwareManufacturer = "Apple", + FirmwareBrand = "iPhone OS", + FirmwareType = firmwareType, + } }; } } diff --git a/POGOLib.Official/Util/Device/DeviceWrapper.cs b/POGOLib.Official/Util/Device/DeviceWrapper.cs new file mode 100644 index 000000000..568ad068b --- /dev/null +++ b/POGOLib.Official/Util/Device/DeviceWrapper.cs @@ -0,0 +1,11 @@ +using static POGOProtos.Networking.Envelopes.Signature.Types; + +namespace POGOLib.Official.Util.Device +{ + public class DeviceWrapper + { + public string UserAgent { get; set; } + + public DeviceInfo DeviceInfo { get; set; } + } +} diff --git a/POGOLib.Official/Util/Encryption/PokeHash/PCryptPokeHash.cs b/POGOLib.Official/Util/Encryption/PokeHash/PCryptPokeHash.cs index d55d7f1e7..ccf18ef99 100644 --- a/POGOLib.Official/Util/Encryption/PokeHash/PCryptPokeHash.cs +++ b/POGOLib.Official/Util/Encryption/PokeHash/PCryptPokeHash.cs @@ -17,10 +17,8 @@ internal static class PCryptPokeHash (byte) 0xE9, (byte) 0x8B, (byte) 0xE8, (byte) 0x39, (byte) 0xD8, (byte) 0x89, (byte) 0x8F, (byte) 0x5A, (byte) 0x3B, (byte) 0x51, (byte) 0x2E, (byte) 0xA9, (byte) 0x47, (byte) 0x38, (byte) 0xC4, (byte) 0x14 }; - - public static object _twoFish { get; private set; } - - public static byte[] MakeIv(Rand rand) + + public static byte[] MakeIv(Rand rand) { byte[] iv = new byte[TwoFish.BLOCK_SIZE]; for (int i = 0; i < iv.Length; i++) diff --git a/PokemonGo-UWP/App.xaml.cs b/PokemonGo-UWP/App.xaml.cs index 318a509bd..3a69f7f95 100644 --- a/PokemonGo-UWP/App.xaml.cs +++ b/PokemonGo-UWP/App.xaml.cs @@ -373,6 +373,7 @@ public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs // See if there is a key for the PokeHash server, ask one from the user if there isn't if (String.IsNullOrEmpty(SettingsService.Instance.PokehashAuthKey)) { + HockeyClient.Current.TrackPageView("PokehashKeyPage"); await NavigationService.NavigateAsync(typeof(PokehashKeyPage), GameMapNavigationModes.AppStart); return; @@ -381,6 +382,7 @@ public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs var currentAccessToken = GameClient.GetAccessToken(); if (currentAccessToken == null || forceToMainPage) { + HockeyClient.Current.TrackPageView("MainPage"); await NavigationService.NavigateAsync(typeof(MainPage)); return; } @@ -391,6 +393,7 @@ public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs await GameClient.InitializeSession(); if (GameClient.IsInitialized) { + HockeyClient.Current.TrackPageView("GameMapPage"); NavigationService.Navigate(typeof(GameMapPage), GameMapNavigationModes.AppStart); } } @@ -400,6 +403,7 @@ public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs ConfirmationDialog dialog = new Views.ConfirmationDialog(errorMessage); dialog.Show(); + HockeyClient.Current.TrackPageView("MainPage"); await NavigationService.NavigateAsync(typeof(MainPage)); } catch (LocationException) @@ -428,6 +432,7 @@ public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs ConfirmationDialog dialog = new Views.ConfirmationDialog(errorMessage); dialog.Show(); + HockeyClient.Current.TrackPageView("PokehashKeyPage"); await NavigationService.NavigateAsync(typeof(PokehashKeyPage), GameMapNavigationModes.AppStart); } } diff --git a/PokemonGo-UWP/Package.appxmanifest b/PokemonGo-UWP/Package.appxmanifest index 8d76f3840..b0fc62b8d 100644 --- a/PokemonGo-UWP/Package.appxmanifest +++ b/PokemonGo-UWP/Package.appxmanifest @@ -1,6 +1,6 @@  - + PoGo diff --git a/PokemonGo-UWP/Utils/GameClient.cs b/PokemonGo-UWP/Utils/GameClient.cs index cee85a6e4..ada6d8e5e 100644 --- a/PokemonGo-UWP/Utils/GameClient.cs +++ b/PokemonGo-UWP/Utils/GameClient.cs @@ -52,6 +52,7 @@ using POGOProtos.Data.Battle; using PokemonGo_UWP.Exceptions; using POGOLib.Official.Net.Captcha; +using Microsoft.HockeyApp; namespace PokemonGo_UWP.Utils { @@ -380,6 +381,8 @@ public static AccessToken GetAccessToken() } catch (Exception) { + HockeyClient.Current.TrackEvent("AccessToken has invalid format"); + SettingsService.Instance.AccessTokenString = null; SettingsService.Instance.UserCredentials = null; return null; @@ -391,6 +394,9 @@ public static AccessToken GetAccessToken() /// private async static Task CreateSession(Geoposition pos) { + Stopwatch sw = new Stopwatch(); + sw.Start(); + if (_session != null) { _session.AccessTokenUpdated -= SessionOnAccessTokenUpdated; @@ -452,6 +458,9 @@ private async static Task CreateSession(Geoposition pos) _session.RpcClient.HatchedEggsReceived += SessionOnHatchedEggsReceived; _session.RpcClient.CheckAwardedBadgesReceived += SessionOnCheckAwardedBadgesReceived; + sw.Stop(); + HockeyClient.Current.TrackMetric("Login time", sw.ElapsedMilliseconds); + await Task.CompletedTask; } @@ -690,12 +699,20 @@ public static async Task GetGameSettings() { Busy.SetBusy(true, "Getting game settings"); + Stopwatch sw = new Stopwatch(); + sw.Start(); + // Momentarily start the session, to retrieve game settings, inventory and player if (!await _session.StartupAsync()) { + sw.Stop(); + HockeyClient.Current.TrackMetric("Getting game settings failed after", sw.ElapsedMilliseconds); throw new Exception("Session couldn't start up."); } + sw.Stop(); + HockeyClient.Current.TrackMetric("Getting game settings took", sw.ElapsedMilliseconds); + // Copy the Game Settings and Player Stats locally GameSetting = _session.GlobalSettings; PlayerStats = _session.Player.Stats; diff --git a/PokemonGo-UWP/ViewModels/AchievementDetailPageViewModel.cs b/PokemonGo-UWP/ViewModels/AchievementDetailPageViewModel.cs index 1c3b6ab61..98d7e2cc8 100644 --- a/PokemonGo-UWP/ViewModels/AchievementDetailPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/AchievementDetailPageViewModel.cs @@ -5,6 +5,7 @@ using PokemonGo_UWP.Utils; using Template10.Mvvm; using Template10.Services.NavigationService; +using Microsoft.HockeyApp; namespace PokemonGo_UWP.ViewModels { public class AchievementDetailPageViewModel : ViewModelBase { @@ -73,7 +74,13 @@ public KeyValuePair Achievement /// /// Going back to map page /// - public DelegateCommand ReturnToProfileScreen => _returnToRProfileScreen ?? (_returnToRProfileScreen = new DelegateCommand(() => { NavigationService.GoBack(); }, () => true)); + public DelegateCommand ReturnToProfileScreen => + _returnToRProfileScreen ?? (_returnToRProfileScreen = new DelegateCommand(() => + { + HockeyClient.Current.TrackEvent("GoBack from AchievementDetailPage"); + NavigationService.GoBack(); + }, + () => true)); #endregion diff --git a/PokemonGo-UWP/ViewModels/ActionLogPageViewModel.cs b/PokemonGo-UWP/ViewModels/ActionLogPageViewModel.cs index e2ea55eef..5fc042e52 100644 --- a/PokemonGo-UWP/ViewModels/ActionLogPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/ActionLogPageViewModel.cs @@ -1,4 +1,5 @@ -using POGOProtos.Data.Logs; +using Microsoft.HockeyApp; +using POGOProtos.Data.Logs; using POGOProtos.Networking.Responses; using PokemonGo_UWP.Utils; using PokemonGo_UWP.Views; @@ -100,7 +101,13 @@ private async void ReadActionLog() /// /// Going back to profile page /// - public DelegateCommand ReturnToProfileScreen => _returnToProfileScreen ?? (_returnToProfileScreen = new DelegateCommand(() => { NavigationService.GoBack(); }, () => true)); + public DelegateCommand ReturnToProfileScreen => + _returnToProfileScreen ?? (_returnToProfileScreen = new DelegateCommand(() => + { + HockeyClient.Current.TrackEvent("GoBack from ActionLogPage"); + NavigationService.GoBack(); + }, + () => true)); #endregion diff --git a/PokemonGo-UWP/ViewModels/CapturePokemonPageViewModel.cs b/PokemonGo-UWP/ViewModels/CapturePokemonPageViewModel.cs index 48061a996..e47145f77 100644 --- a/PokemonGo-UWP/ViewModels/CapturePokemonPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/CapturePokemonPageViewModel.cs @@ -21,6 +21,7 @@ using Windows.UI.Xaml; using PokemonGo_UWP.Utils.Game; using POGOLib.Official.Logging; +using Microsoft.HockeyApp; namespace PokemonGo_UWP.ViewModels { @@ -372,6 +373,7 @@ public PokemonSettings PokemonExtraData { if (CurrentPokemon.EncounterId == 0) // Starter Pokemon, return to Tutorial page { + HockeyClient.Current.TrackPageView("TutorialPage"); NavigationService.Navigate(typeof(TutorialPage), TutorialNavigationModes.StarterPokemonCatched); return; } @@ -379,6 +381,7 @@ public PokemonSettings PokemonExtraData GameClient.ToggleUpdateTimer(); if (currentPokemon != null) { + HockeyClient.Current.TrackPageView("PokemonDetailPage"); NavigationService.Navigate(typeof(PokemonDetailPage), new SelectedPokemonNavModel() { SelectedPokemonId = _capturedPokemonId.ToString(), @@ -387,6 +390,7 @@ public PokemonSettings PokemonExtraData } else { + HockeyClient.Current.TrackPageView("GameMapPage"); NavigationService.Navigate(typeof(GameMapPage), GameMapNavigationModes.PokemonUpdate); } }, () => true)); @@ -404,7 +408,11 @@ public PokemonSettings PokemonExtraData GameClient.ToggleUpdateTimer(); } - Dispatcher.Dispatch(() => NavigationService.GoBack()); + Dispatcher.Dispatch(() => + { + HockeyClient.Current.TrackEvent("GoBack from CapturePokemonPage"); + NavigationService.GoBack(); + }); }, () => true)); #endregion diff --git a/PokemonGo-UWP/ViewModels/EggDetailPageViewModel.cs b/PokemonGo-UWP/ViewModels/EggDetailPageViewModel.cs index 53129ba29..84155519e 100644 --- a/PokemonGo-UWP/ViewModels/EggDetailPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/EggDetailPageViewModel.cs @@ -11,6 +11,7 @@ using POGOProtos.Networking.Responses; using Template10.Mvvm; using POGOLib.Official.Logging; +using Microsoft.HockeyApp; namespace PokemonGo_UWP.ViewModels { @@ -94,6 +95,7 @@ public PokemonDataWrapper SelectedEgg public DelegateCommand ReturnToPokemonInventoryScreen => _returnToPokemonInventoryScreen ?? ( _returnToPokemonInventoryScreen = new DelegateCommand(() => { + HockeyClient.Current.TrackEvent("GoBack from EggDetailPage"); NavigationService.GoBack(); }, () => true)); diff --git a/PokemonGo-UWP/ViewModels/EnterGymPageViewModel.cs b/PokemonGo-UWP/ViewModels/EnterGymPageViewModel.cs index 1af03e559..9cb1dddcb 100644 --- a/PokemonGo-UWP/ViewModels/EnterGymPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/EnterGymPageViewModel.cs @@ -26,6 +26,7 @@ using POGOLib.Official.Net; using System.Diagnostics; using POGOProtos.Map.Fort; +using Microsoft.HockeyApp; namespace PokemonGo_UWP.ViewModels { @@ -370,8 +371,11 @@ public PokemonData UltimatePokemon /// public DelegateCommand ReturnToGameScreen => _returnToGameScreen ?? ( _returnToGameScreen = - new DelegateCommand( - () => { NavigationService.Navigate(typeof(GameMapPage), GameMapNavigationModes.GymUpdate); }, + new DelegateCommand(() => + { + HockeyClient.Current.TrackPageView("GameMapPage"); + NavigationService.Navigate(typeof(GameMapPage), GameMapNavigationModes.GymUpdate); + }, () => true) ); @@ -385,6 +389,7 @@ public PokemonData UltimatePokemon { // Re-enable update timer GameClient.ToggleUpdateTimer(); + HockeyClient.Current.TrackEvent("GoBack from EnterGymPage"); NavigationService.GoBack(); }, () => true) ); diff --git a/PokemonGo-UWP/ViewModels/GameMapPageViewModel.cs b/PokemonGo-UWP/ViewModels/GameMapPageViewModel.cs index 38da0b06f..73d7a9753 100644 --- a/PokemonGo-UWP/ViewModels/GameMapPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/GameMapPageViewModel.cs @@ -25,6 +25,7 @@ using POGOProtos.Inventory; using PokemonGo_UWP.Utils.Game; using POGOLib.Official.Logging; +using Microsoft.HockeyApp; namespace PokemonGo_UWP.ViewModels { @@ -126,6 +127,7 @@ public override async Task OnNavigatedToAsync(object parameter, NavigationMode m // Go into the Tutorial Mode until the playerprofile is in the correct state if (!CheckTutorialStateOk()) { + HockeyClient.Current.TrackPageView("TutorialPage"); await NavigationService.NavigateAsync(typeof(TutorialPage), TutorialNavigationModes.TutorialStart); return; } @@ -365,7 +367,11 @@ public async Task UpdatePlayerData(bool checkForLevelUp = false) public DelegateCommand SettingsCommand => _openSettingsCommand ?? - (_openSettingsCommand = new DelegateCommand(() => { NavigationService.Navigate(typeof(SettingsPage)); })) + (_openSettingsCommand = new DelegateCommand(() => + { + HockeyClient.Current.TrackPageView("SettingsPage"); + NavigationService.Navigate(typeof(SettingsPage)); + })) ; #endregion @@ -377,8 +383,11 @@ public DelegateCommand SettingsCommand public DelegateCommand GotoPokemonInventoryPageCommand => _gotoPokemonInventoryPage ?? - (_gotoPokemonInventoryPage = - new DelegateCommand(() => { NavigationService.Navigate(typeof(PokemonInventoryPage), true); })); + (_gotoPokemonInventoryPage = new DelegateCommand(() => + { + HockeyClient.Current.TrackPageView("PokemonInventoryPage"); + NavigationService.Navigate(typeof(PokemonInventoryPage), true); + })); #endregion @@ -389,8 +398,11 @@ public DelegateCommand GotoPokemonInventoryPageCommand public DelegateCommand GotoItemsInventoryPageCommand => _gotoItemsInventoryPage ?? - (_gotoItemsInventoryPage = - new DelegateCommand(() => { NavigationService.Navigate(typeof(ItemsInventoryPage), true); })); + (_gotoItemsInventoryPage = new DelegateCommand(() => + { + HockeyClient.Current.TrackPageView("ItemsInventoryPage"); + NavigationService.Navigate(typeof(ItemsInventoryPage), true); + })); #endregion @@ -401,15 +413,21 @@ public DelegateCommand GotoItemsInventoryPageCommand public DelegateCommand GotoPlayerProfilePageCommand => _gotoPlayerProfilePage ?? - (_gotoPlayerProfilePage = - new DelegateCommand(() => { NavigationService.Navigate(typeof(PlayerProfilePage), true); })); + (_gotoPlayerProfilePage = new DelegateCommand(() => + { + HockeyClient.Current.TrackPageView("PlayerProfilePage"); + NavigationService.Navigate(typeof(PlayerProfilePage), true); + })); private DelegateCommand _gotoPokedexPage; public DelegateCommand GotoPokedexPageCommand => _gotoPokedexPage ?? - (_gotoPokedexPage = - new DelegateCommand(() => { NavigationService.Navigate(typeof(PokedexPage)); })); + (_gotoPokedexPage = new DelegateCommand(() => + { + HockeyClient.Current.TrackPageView("PokedexPage"); + NavigationService.Navigate(typeof(PokedexPage)); + })); #endregion diff --git a/PokemonGo-UWP/ViewModels/ItemsInventoryPageViewModel.cs b/PokemonGo-UWP/ViewModels/ItemsInventoryPageViewModel.cs index 730dd7725..549b420d5 100644 --- a/PokemonGo-UWP/ViewModels/ItemsInventoryPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/ItemsInventoryPageViewModel.cs @@ -16,6 +16,7 @@ using POGOProtos.Data; using PokemonGo_UWP.Utils.Extensions; using POGOProtos.Inventory.Item; +using Microsoft.HockeyApp; namespace PokemonGo_UWP.ViewModels { @@ -179,8 +180,11 @@ public PokemonDataWrapper SelectedPokemon public DelegateCommand ReturnToGameScreen => _returnToGameScreen ?? - (_returnToGameScreen = - new DelegateCommand(() => { NavigationService.Navigate(typeof(GameMapPage)); }, () => true)); + (_returnToGameScreen = new DelegateCommand(() => + { + HockeyClient.Current.TrackPageView("GameMapPage"); + NavigationService.Navigate(typeof(GameMapPage)); + }, () => true)); public int MaxItemStorageFieldNumber => GameClient.PlayerData.MaxItemStorage; diff --git a/PokemonGo-UWP/ViewModels/LoginPageViewModel.cs b/PokemonGo-UWP/ViewModels/LoginPageViewModel.cs index 431234483..a7ffa0c64 100644 --- a/PokemonGo-UWP/ViewModels/LoginPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/LoginPageViewModel.cs @@ -145,6 +145,7 @@ public bool RememberLoginData GameClient.LoggedIn = true; // Goto game page + HockeyClient.Current.TrackPageView("GameMapPage"); await NavigationService.NavigateAsync(typeof(GameMapPage), GameMapNavigationModes.AppStart); } } @@ -201,6 +202,7 @@ public bool RememberLoginData GameClient.LoggedIn = true; // Goto game page + HockeyClient.Current.TrackPageView("GameMapPage"); await NavigationService.NavigateAsync(typeof(GameMapPage), GameMapNavigationModes.AppStart); } } diff --git a/PokemonGo-UWP/ViewModels/PlayerProfileViewModel.cs b/PokemonGo-UWP/ViewModels/PlayerProfileViewModel.cs index e0671c42d..9622c8f21 100644 --- a/PokemonGo-UWP/ViewModels/PlayerProfileViewModel.cs +++ b/PokemonGo-UWP/ViewModels/PlayerProfileViewModel.cs @@ -17,6 +17,7 @@ using POGOProtos.Networking.Responses; using POGOProtos.Data.Logs; using Template10.Utils; +using Microsoft.HockeyApp; namespace PokemonGo_UWP.ViewModels { @@ -127,7 +128,11 @@ public PlayerStats PlayerStats public DelegateCommand ReturnToGameScreen => _returnToGameScreen ?? - (_returnToGameScreen = new DelegateCommand(() => { NavigationService.GoBack(); }, () => true)); + (_returnToGameScreen = new DelegateCommand(() => + { + HockeyClient.Current.TrackEvent("GoBack from PlayerProfilePage"); + NavigationService.GoBack(); + }, () => true)); #endregion @@ -198,6 +203,7 @@ private void ReadPlayerStatsValues() public DelegateCommand GoToAchievementDetailPage => m_GoToAchievementDetailPage ?? (m_GoToAchievementDetailPage = new DelegateCommand(x => { + HockeyClient.Current.TrackPageView("AchievementDetailPage"); BootStrapper.Current.NavigationService.Navigate(typeof(AchievementDetailPage), x); })); @@ -209,6 +215,7 @@ private void ReadPlayerStatsValues() public DelegateCommand GoToActionLogPage => _gotoActionLogPage ?? (_gotoActionLogPage = new DelegateCommand(() => { + HockeyClient.Current.TrackPageView("ActionLogPage"); BootStrapper.Current.NavigationService.Navigate(typeof(ActionLogPage)); })); #endregion diff --git a/PokemonGo-UWP/ViewModels/PokedexDetailViewModel.cs b/PokemonGo-UWP/ViewModels/PokedexDetailViewModel.cs index fed71cef2..6437f3b60 100644 --- a/PokemonGo-UWP/ViewModels/PokedexDetailViewModel.cs +++ b/PokemonGo-UWP/ViewModels/PokedexDetailViewModel.cs @@ -7,6 +7,7 @@ using PokemonGo_UWP.Utils; using POGOProtos.Enums; using Template10.Mvvm; +using Microsoft.HockeyApp; namespace PokemonGo_UWP.ViewModels { @@ -63,6 +64,7 @@ public DelegateCommand CloseCommand _closeCommand ?? (_closeCommand = new DelegateCommand(() => { + HockeyClient.Current.TrackEvent("GoBack from PokedexDetailPage"); NavigationService.GoBack(); }, () => true) ); diff --git a/PokemonGo-UWP/ViewModels/PokedexPageViewModel.cs b/PokemonGo-UWP/ViewModels/PokedexPageViewModel.cs index 608c256d6..ce73d7267 100644 --- a/PokemonGo-UWP/ViewModels/PokedexPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/PokedexPageViewModel.cs @@ -1,4 +1,5 @@ -using POGOProtos.Data; +using Microsoft.HockeyApp; +using POGOProtos.Data; using POGOProtos.Enums; using POGOProtos.Settings.Master; using PokemonGo_UWP.Utils; @@ -66,6 +67,7 @@ public override Task OnNavigatedToAsync(object parameter, NavigationMode mode, I if (parameter is PokemonId) { + HockeyClient.Current.TrackPageView("PokedexDetailPage"); NavigationService.Navigate(typeof(PokedexDetailPage), (PokemonId)parameter); } @@ -117,6 +119,7 @@ public override Task OnNavigatedFromAsync(IDictionary pageState, (id) => { if (GameClient.PokedexInventory.All(x => x.PokemonId != id)) return; + HockeyClient.Current.TrackPageView("PokedexDetailPage"); NavigationService.Navigate(typeof(PokedexDetailPage), id); }, (x) => true) @@ -128,6 +131,7 @@ public DelegateCommand CloseCommand _closeCommand ?? (_closeCommand = new DelegateCommand(() => { + HockeyClient.Current.TrackEvent("GoBack from PokedexPage"); NavigationService.GoBack(); }, () => true) ); diff --git a/PokemonGo-UWP/ViewModels/PokehashKeyPageViewModel.cs b/PokemonGo-UWP/ViewModels/PokehashKeyPageViewModel.cs index d83e1a4c7..f8947df59 100644 --- a/PokemonGo-UWP/ViewModels/PokehashKeyPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/PokehashKeyPageViewModel.cs @@ -20,6 +20,7 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Navigation; using POGOLib.Official.Util.Hash.PokeHash; +using Microsoft.HockeyApp; namespace PokemonGo_UWP.ViewModels { @@ -118,6 +119,7 @@ public string PokehashKey await GameClient.InitializeSession(); if (GameClient.IsInitialized) { + HockeyClient.Current.TrackPageView("GameMapPage"); await NavigationService.NavigateAsync(typeof(GameMapPage), GameMapNavigationModes.AppStart); } } @@ -127,6 +129,7 @@ public string PokehashKey ConfirmationDialog dialog = new Views.ConfirmationDialog(errorMessage); dialog.Show(); + HockeyClient.Current.TrackPageView("MainPage"); await NavigationService.NavigateAsync(typeof(MainPage)); } catch (LocationException) @@ -156,11 +159,13 @@ public string PokehashKey } else { + HockeyClient.Current.TrackPageView("MainPage"); await NavigationService.NavigateAsync(typeof(MainPage)); } } else { + HockeyClient.Current.TrackPageView("MainPage"); await NavigationService.NavigateAsync(typeof(MainPage)); } diff --git a/PokemonGo-UWP/ViewModels/PokemonDetailPageViewModel.cs b/PokemonGo-UWP/ViewModels/PokemonDetailPageViewModel.cs index ac0fc05e5..d71272444 100644 --- a/PokemonGo-UWP/ViewModels/PokemonDetailPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/PokemonDetailPageViewModel.cs @@ -19,6 +19,7 @@ using PokemonGo_UWP.Controls; using PokemonGo_UWP.Views; using PokemonGo_UWP.Utils.Extensions; +using Microsoft.HockeyApp; namespace PokemonGo_UWP.ViewModels { @@ -227,6 +228,7 @@ public bool PlayerTeamIsSet _closePokemonDetailPage = new DelegateCommand(() => { if (ServerRequestRunning) return; + HockeyClient.Current.TrackEvent("GoBack from PokemonDetailPage"); NavigationService.GoBack(); }, () => true) ); @@ -309,6 +311,7 @@ public bool PlayerTeamIsSet // TODO: Implement message informing about success of transfer (Shell needed) //GameClient.UpdateInventory(); await GameClient.UpdatePlayerStats(); + HockeyClient.Current.TrackEvent("GoBack from PokemonDetailPage"); NavigationService.GoBack(); break; @@ -657,6 +660,7 @@ private bool CanEvolve() public DelegateCommand NavigateToEvolvedPokemonCommand => _navigateToEvolvedPokemonCommand ?? (_navigateToEvolvedPokemonCommand = new DelegateCommand(() => { + HockeyClient.Current.TrackPageView("PokemonDetailPage"); NavigationService.Navigate(typeof(PokemonDetailPage), new SelectedPokemonNavModel() { SelectedPokemonId = EvolvedPokemon.Id.ToString(), diff --git a/PokemonGo-UWP/ViewModels/PokemonInventoryPageViewModel.cs b/PokemonGo-UWP/ViewModels/PokemonInventoryPageViewModel.cs index eb22ae98e..ac2959af1 100644 --- a/PokemonGo-UWP/ViewModels/PokemonInventoryPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/PokemonInventoryPageViewModel.cs @@ -16,6 +16,7 @@ using Windows.UI.Xaml.Media.Animation; using PokemonGo_UWP.Controls; using POGOProtos.Networking.Responses; +using Microsoft.HockeyApp; namespace PokemonGo_UWP.ViewModels { @@ -217,6 +218,7 @@ public int TotalPokemonCount { _returnToGameScreen = new DelegateCommand(() => { if (ServerRequestRunning) return; + HockeyClient.Current.TrackEvent("GoBack from PokemonInventoryPage"); NavigationService.GoBack(); }, () => true)); @@ -252,6 +254,7 @@ private void UpdateSorting() } else { + HockeyClient.Current.TrackPageView("PokemonDetailPage"); NavigationService.Navigate(typeof(PokemonDetailPage), new SelectedPokemonNavModel() { SelectedPokemonId = selectedPokemon.Id.ToString(), @@ -267,6 +270,7 @@ private void UpdateSorting() private DelegateCommand _gotoEggDetailCommand; public DelegateCommand GotoEggDetailCommand => _gotoEggDetailCommand ?? (_gotoEggDetailCommand = new DelegateCommand((selectedEgg) => { + HockeyClient.Current.TrackPageView("EggDetailPage"); NavigationService.Navigate(typeof(EggDetailPage), selectedEgg.Id.ToString(), new SuppressNavigationTransitionInfo()); })); diff --git a/PokemonGo-UWP/ViewModels/SearchPokeStopPageViewModel.cs b/PokemonGo-UWP/ViewModels/SearchPokeStopPageViewModel.cs index c9174c818..a98333f25 100644 --- a/PokemonGo-UWP/ViewModels/SearchPokeStopPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/SearchPokeStopPageViewModel.cs @@ -15,6 +15,7 @@ using Google.Protobuf; using POGOLib.Official.Logging; using PokemonGo_UWP.Utils.Extensions; +using Microsoft.HockeyApp; namespace PokemonGo_UWP.ViewModels { @@ -236,8 +237,11 @@ public bool IsPokestopLured /// public DelegateCommand ReturnToGameScreen => _returnToGameScreen ?? ( _returnToGameScreen = - new DelegateCommand( - () => { NavigationService.Navigate(typeof(GameMapPage), GameMapNavigationModes.PokestopUpdate); }, + new DelegateCommand(() => + { + HockeyClient.Current.TrackPageView("GameMapPage"); + NavigationService.Navigate(typeof(GameMapPage), GameMapNavigationModes.PokestopUpdate); + }, () => true) ); diff --git a/PokemonGo-UWP/ViewModels/SettingsPageViewModel.cs b/PokemonGo-UWP/ViewModels/SettingsPageViewModel.cs index be88c4f21..0db429750 100644 --- a/PokemonGo-UWP/ViewModels/SettingsPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/SettingsPageViewModel.cs @@ -1,4 +1,5 @@ -using PokemonGo_UWP.Entities; +using Microsoft.HockeyApp; +using PokemonGo_UWP.Entities; using PokemonGo_UWP.Utils; using PokemonGo_UWP.Views; using System.Collections.Generic; @@ -190,6 +191,7 @@ public SettingsPageViewModel() // Clear stored token GameClient.DoLogout(); // Navigate to login page + HockeyClient.Current.TrackPageView("MainPage"); NavigationService.Navigate(typeof(MainPage)); // Remove all pages from the history NavigationService.ClearHistory(); @@ -210,10 +212,12 @@ public SettingsPageViewModel() // Navigate back if we didn't change map settings if (_mapSettingsChangedCounter%2 == 0) { + HockeyClient.Current.TrackEvent("GoBack from SettingsPage"); NavigationService.GoBack(); } else { + HockeyClient.Current.TrackPageView("GameMapPage"); NavigationService.Navigate(typeof(GameMapPage), GameMapNavigationModes.SettingsUpdate); } })); diff --git a/PokemonGo-UWP/ViewModels/TutorialPageViewModel.cs b/PokemonGo-UWP/ViewModels/TutorialPageViewModel.cs index d7cc4a224..d166e19d5 100644 --- a/PokemonGo-UWP/ViewModels/TutorialPageViewModel.cs +++ b/PokemonGo-UWP/ViewModels/TutorialPageViewModel.cs @@ -1,4 +1,5 @@ using Google.Protobuf.Collections; +using Microsoft.HockeyApp; using Newtonsoft.Json; using POGOProtos.Data; using POGOProtos.Data.Player; @@ -415,6 +416,7 @@ public async Task MarkNameSelectionComplete() } AudioUtils.StopSounds(); + HockeyClient.Current.TrackPageView("GameMapPage"); await NavigationService.NavigateAsync(typeof(GameMapPage), GameMapNavigationModes.AppStart); }, () => true)); #endregion @@ -436,6 +438,7 @@ public async Task MarkNameSelectionComplete() AudioUtils.StopSounds(); + HockeyClient.Current.TrackPageView("GameMapPage"); await NavigationService.NavigateAsync(typeof(GameMapPage), GameMapNavigationModes.AppStart); }, () => true)); diff --git a/PokemonGo-UWP/project.json b/PokemonGo-UWP/project.json index 104356783..70e1e692a 100644 --- a/PokemonGo-UWP/project.json +++ b/PokemonGo-UWP/project.json @@ -1,7 +1,7 @@ { "dependencies": { "Google.Protobuf.Tools": "3.1.0", - "HockeySDK.UWP": "4.1.5", + "HockeySDK.UWP": "4.1.6", "Microsoft.NETCore.UniversalWindowsPlatform": "5.2.2", "Newtonsoft.Json": "9.0.1", "Nito.AsyncEx": "3.0.1", diff --git a/version.json b/version.json index eec95fc08..f0fcba01b 100644 --- a/version.json +++ b/version.json @@ -5,8 +5,8 @@ "version_number": 6100, "settings_updated": "2017-02-19T00:00:00", "latest_release": { - "version": "1.3.2", - "setup_file": "https://github.com/mtaheij/PoGo-UWP/releases/download/v1.3.2-beta/PokemonGo-UWP_1.3.2.0_{arch}.appxbundle", + "version": "1.3.3", + "setup_file": "https://github.com/mtaheij/PoGo-UWP/releases/download/v1.3.3-beta/PokemonGo-UWP_1.3.3.0_{arch}.appxbundle", "dependencies": [ ] }