Skip to content

Commit

Permalink
Added HockeyApp client
Browse files Browse the repository at this point in the history
  • Loading branch information
mtaheij committed Apr 21, 2017
1 parent 0016998 commit 9005109
Show file tree
Hide file tree
Showing 31 changed files with 264 additions and 87 deletions.
6 changes: 2 additions & 4 deletions POGOLib.Official/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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";

}
}
27 changes: 13 additions & 14 deletions POGOLib.Official/Net/Authentication/Login.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -20,16 +20,16 @@ public static class Login
/// <param name="accessToken"></param>
/// <param name="initialLatitude">The initial latitude you will spawn at after logging into PokémonGo.</param>
/// <param name="initialLongitude">The initial longitude you will spawn at after logging into PokémonGo.</param>
/// <param name="deviceInfo">The <see cref="DeviceInfo"/> used by the <see cref="Session"/>, keep null if you want a randomly generated <see cref="DeviceInfo"/>.</param>
/// <param name="deviceWrapper">The <see cref="DeviceWrapper"/> used by the <see cref="Session"/>, keep null if you want a randomly generated <see cref="DeviceWrapper"/>.</param>
/// <returns></returns>
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);
}

/// <summary>
Expand All @@ -38,11 +38,11 @@ public static Session GetSession(ILoginProvider loginProvider, AccessToken acces
/// <param name="loginProvider">The OAuth provider you use to authenticate.</param>
/// <param name="initialLatitude">The initial latitude you will spawn at after logging into PokémonGo.</param>
/// <param name="initialLongitude">The initial longitude you will spawn at after logging into PokémonGo.</param>
/// <param name="deviceInfo">The <see cref="DeviceInfo"/> used by the <see cref="Session"/>, keep null if you want a randomly generated <see cref="DeviceInfo"/>.</param>
/// <param name="deviceWrapper">The <see cref="DeviceWrapper"/> used by the <see cref="Session"/>, keep null if you want a randomly generated <see cref="DeviceWrapper"/>.</param>
/// <returns></returns>
public static async Task<Session> GetSession(ILoginProvider loginProvider, double initialLatitude, double initialLongitude, DeviceInfo deviceInfo = null)
public static async Task<Session> 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);
}

/// <summary>
Expand All @@ -51,30 +51,29 @@ public static async Task<Session> GetSession(ILoginProvider loginProvider, doubl
/// <param name="loginProvider">The OAuth provider you use to authenticate.</param>
/// <param name="accessToken">The <see cref="AccessToken"/> you want to re-use.</param>
/// <param name="coordinate">The initial coordinate you will spawn at after logging into PokémonGo.</param>
/// <param name="deviceInfo">The <see cref="DeviceInfo"/> used by the <see cref="Session"/>, keep null if you want a randomly generated <see cref="DeviceInfo"/>.</param>
/// <param name="deviceWrapper">The <see cref="DeviceWrapper"/> used by the <see cref="Session"/>, keep null if you want a randomly generated <see cref="DeviceWrapper"/>.</param>
/// <returns></returns>
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)
{
throw new ArgumentException($"{nameof(accessToken)} is expired.");
}

Logger.Debug("Authenticated from cache.");
return new Session(loginProvider, accessToken, coordinate, deviceInfo);
return new Session(loginProvider, accessToken, coordinate, deviceWrapper);
}

/// <summary>
/// Login through OAuth with PTC / Google.
/// </summary>
/// <param name="loginProvider">The OAuth provider you use to authenticate.</param>
/// <param name="coordinate">The initial coordinate you will spawn at after logging into PokémonGo.</param>
/// <param name="deviceInfo">The <see cref="DeviceInfo"/> used by the <see cref="Session"/>, keep null if you want a randomly generated <see cref="DeviceInfo"/>.</param>
/// <param name="deviceWrapper">The <see cref="DeviceWrapper"/> used by the <see cref="Session"/>, keep null if you want a randomly generated <see cref="DeviceWrapper"/>.</param>
/// <returns></returns>
public static async Task<Session> GetSession(ILoginProvider loginProvider, GeoCoordinate coordinate, DeviceInfo deviceInfo = null)
public static async Task<Session> 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);
}

}
}
17 changes: 13 additions & 4 deletions POGOLib.Official/Net/RpcClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -116,20 +117,27 @@ internal async Task<bool> 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()
}
});
Expand All @@ -138,7 +146,8 @@ internal async Task<bool> StartupAsync()
{
await Task.Delay(TimeSpan.FromMilliseconds(1000));
}
} while (!playerResponse.Success);
loop++;
} while (!playerResponse.Success && loop < 10);

_session.Player.Data = playerResponse.PlayerData;

Expand Down
2 changes: 1 addition & 1 deletion POGOLib.Official/Net/RpcEncryption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ internal async Task<PlatformRequest> GenerateSignatureAsync(RequestEnvelope requ
Status = 3
}
},
DeviceInfo = _session.DeviceInfo,
DeviceInfo = _session.Device.DeviceInfo,
LocationFix = { locationFixes },
ActivityStatus = new ActivityStatus
{
Expand Down
37 changes: 21 additions & 16 deletions POGOLib.Official/Net/Session.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -44,23 +45,23 @@ 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))
{
throw new ArgumentException($"LoginProvider ID must be one of the following: {string.Join(", ", ValidLoginProviders)}");
}

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);
Expand Down Expand Up @@ -89,14 +90,14 @@ private set
internal Random Random { get; private set; } = new Random();

/// <summary>
/// Gets the <see cref="HttpClient"/> of the <see cref="Session"/>.
/// Gets the <see cref="DeviceWrapper"/> used by <see cref="RpcEncryption"/>.
/// </summary>
internal HttpClient HttpClient { get; }
public DeviceWrapper Device { get; private set; }

/// <summary>
/// Gets the <see cref="DeviceInfo"/> used by <see cref="RpcEncryption"/>.
/// Gets the <see cref="HttpClient"/> of the <see cref="Session"/>.
/// </summary>
public DeviceInfo DeviceInfo { get; private set; }
internal HttpClient HttpClient { get; }

/// <summary>
/// Gets the <see cref="ILoginProvider"/> used to obtain an <see cref="AccessToken"/>.
Expand Down Expand Up @@ -198,15 +199,19 @@ public void Shutdown()
/// <returns></returns>
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.");
}
}
}

Expand Down
1 change: 1 addition & 0 deletions POGOLib.Official/POGOLib.Official.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
<Compile Include="Util\Data\IDataCache.cs" />
<Compile Include="Util\Data\MemoryDataCache.cs" />
<Compile Include="Util\Device\DeviceInfoUtil.cs" />
<Compile Include="Util\Device\DeviceWrapper.cs" />
<Compile Include="Util\Encryption\Legacy\NiaHashLegacy.cs" />
<Compile Include="Util\Encryption\Legacy\PCryptLegacy.cs" />
<Compile Include="Util\Encryption\Legacy\ShufflesLegacy.cs" />
Expand Down
80 changes: 62 additions & 18 deletions POGOLib.Official/Util/Device/DeviceInfoUtil.cs
Original file line number Diff line number Diff line change
@@ -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"},
Expand Down Expand Up @@ -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,
}
};
}
}
Expand Down
11 changes: 11 additions & 0 deletions POGOLib.Official/Util/Device/DeviceWrapper.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
}
6 changes: 2 additions & 4 deletions POGOLib.Official/Util/Encryption/PokeHash/PCryptPokeHash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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++)
Expand Down
Loading

0 comments on commit 9005109

Please sign in to comment.