diff --git a/PokemonGo/RocketAPI/Client.cs b/PokemonGo/RocketAPI/Client.cs
index 94ccfa9..1dcbf01 100644
--- a/PokemonGo/RocketAPI/Client.cs
+++ b/PokemonGo/RocketAPI/Client.cs
@@ -20,7 +20,7 @@ using System.Threading;
using PokemonGo.RocketAPI.Exceptions;
using System.Text;
using System.IO;
-using DankMemes.GPSOAuthSharp;
+using Newtonsoft.Json;
#endregion
@@ -32,13 +32,14 @@ namespace PokemonGo.RocketAPI
private ISettings _settings;
private string _accessToken;
private string _apiUrl;
- private AuthType _authType = AuthType.Google;
private double _currentLat;
private double _currentLng;
private Request.Types.UnknownAuth _unknownAuth;
public static string AccessToken { get; set; } = string.Empty;
+ private readonly ILoginType login;
+
public Client(ISettings settings)
{
_settings = settings;
@@ -58,6 +59,20 @@ namespace PokemonGo.RocketAPI
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "*/*");
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type",
"application/x-www-form-urlencoded");
+
+ login = CreateLoginType(settings);
+ }
+
+ static ILoginType CreateLoginType(ISettings settings)
+ {
+ switch (settings.AuthType)
+ {
+ case AuthType.Google:
+ return new GoogleLogin(settings.Email, settings.Password);
+ case AuthType.Ptc:
+ return new PtcLogin(settings.PtcUsername, settings.PtcPassword);
+ }
+ throw new ArgumentOutOfRangeException(nameof(settings.AuthType), "unknown auth type");
}
public async Task<CatchPokemonResponse> CatchPokemon(ulong encounterId, string spawnPointGuid, double pokemonLat,
@@ -86,36 +101,27 @@ namespace PokemonGo.RocketAPI
catchPokemonRequest);
}
- public async Task DoGoogleLogin(string email, string password)
+ public async Task Login()
{
- _authType = AuthType.Google;
- GPSOAuthClient _GPSOclient = new GPSOAuthClient(email, password);
- Dictionary<string, string> _GPSOresponse = _GPSOclient.PerformMasterLogin();
- /* string json = JsonConvert.SerializeObject(_GPSOresponse, Formatting.Indented);
- Console.WriteLine(json); */
- if (_GPSOresponse.ContainsKey("Token"))
+ string errorMessage;
+ do
{
- string token = _GPSOresponse["Token"];
- Dictionary<string, string> oauthResponse = _GPSOclient.PerformOAuth(
- token,
- "audience:server:client_id:848232511240-7so421jotr2609rmqakceuu1luuq0ptb.apps.googleusercontent.com",
- "com.nianticlabs.pokemongo",
- "321187995bc7cdc2b5fc91b11a96e2baa8602c62");
- /* string oauthJson = JsonConvert.SerializeObject(oauthResponse, Formatting.Indented);
- Console.WriteLine(oauthJson); */
- _accessToken = oauthResponse["Auth"];
- }
- }
+ errorMessage = null;
+
+ try
+ {
+ _accessToken = await login.GetAccessToken().ConfigureAwait(false);
+ }
+ catch (LoginFailedException) { errorMessage = "Login failed - wrong username or password? - Restarting"; }
+ catch (PtcOfflineException) { errorMessage = "PTC login server is down - Restarting"; }
+ catch (JsonReaderException) { errorMessage = "Json Reader Exception - Server down? - Restarting"; }
+ catch (Exception ex) { errorMessage = ex.ToString() + "Exception - Please report - Restarting"; }
+
+ if(errorMessage != null)
+ ColoredConsoleWrite(ConsoleColor.White, errorMessage);
+
+ } while (errorMessage != null);
- public async Task DoPtcLogin(string username, string password)
- {
- try
- {
- _accessToken = await PtcLogin.GetAccessToken(username, password);
- _authType = AuthType.Ptc;
- }
- catch (Newtonsoft.Json.JsonReaderException) { ColoredConsoleWrite(ConsoleColor.White, "Json Reader Exception - Server down? - Restarting"); DoPtcLogin(username, password); }
- catch (Exception ex) { ColoredConsoleWrite(ConsoleColor.White, ex.ToString() + "Exception - Please report - Restarting"); DoPtcLogin(username, password); }
}
public async Task<EncounterResponse> EncounterPokemon(ulong encounterId, string spawnPointGuid)
@@ -326,7 +332,7 @@ namespace PokemonGo.RocketAPI
public async Task<GetPlayerResponse> GetProfile()
{
- var profileRequest = RequestBuilder.GetInitialRequest(_accessToken, _authType, _currentLat, _currentLng, 10,
+ var profileRequest = RequestBuilder.GetInitialRequest(_accessToken, _settings.AuthType, _currentLat, _currentLng, 10,
new Request.Types.Requests { Type = (int)RequestType.GET_PLAYER });
return
await _httpClient.PostProtoPayload<Request, GetPlayerResponse>($"https://{_apiUrl}/rpc", profileRequest);
@@ -383,7 +389,7 @@ namespace PokemonGo.RocketAPI
public async Task SetServer()
{
- var serverRequest = RequestBuilder.GetInitialRequest(_accessToken, _authType, _currentLat, _currentLng, 10,
+ var serverRequest = RequestBuilder.GetInitialRequest(_accessToken, _settings.AuthType, _currentLat, _currentLng, 10,
RequestType.GET_PLAYER, RequestType.GET_HATCHED_OBJECTS, RequestType.GET_INVENTORY,
RequestType.CHECK_AWARDED_BADGES, RequestType.DOWNLOAD_SETTINGS);
var serverResponse = await _httpClient.PostProto(Resources.RpcUrl, serverRequest);
diff --git a/PokemonGo/RocketAPI/Exceptions/LoginFailedException.cs b/PokemonGo/RocketAPI/Exceptions/LoginFailedException.cs
new file mode 100644
index 0000000..37bd893
--- /dev/null
+++ b/PokemonGo/RocketAPI/Exceptions/LoginFailedException.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace PokemonGo.RocketAPI.Exceptions
+{
+ public class LoginFailedException : Exception
+ {
+ }
+}
\ No newline at end of file
diff --git a/PokemonGo/RocketAPI/GPSOAuthSharp.cs b/PokemonGo/RocketAPI/GPSOAuthSharp.cs
deleted file mode 100644
index 9415c32..0000000
--- a/PokemonGo/RocketAPI/GPSOAuthSharp.cs
+++ /dev/null
@@ -1,177 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Security.Cryptography;
-using System.Text;
-
-namespace DankMemes.GPSOAuthSharp
-{
- // gpsoauth:__init__.py
- // URL: https://github.com/simon-weber/gpsoauth/blob/master/gpsoauth/__init__.py
- public class GPSOAuthClient
- {
- static string b64Key = "AAAAgMom/1a/v0lblO2Ubrt60J2gcuXSljGFQXgcyZWveWLEwo6prwgi3" +
- "iJIZdodyhKZQrNWp5nKJ3srRXcUW+F1BD3baEVGcmEgqaLZUNBjm057pK" +
- "RI16kB0YppeGx5qIQ5QjKzsR8ETQbKLNWgRY0QRNVz34kMJR3P/LgHax/" +
- "6rmf5AAAAAwEAAQ==";
- static RSAParameters androidKey = GoogleKeyUtils.KeyFromB64(b64Key);
-
- static string version = "0.0.5";
- static string authUrl = "https://android.clients.google.com/auth";
- static string userAgent = "GPSOAuthSharp/" + version;
-
- private string email;
- private string password;
-
- public GPSOAuthClient(string email, string password)
- {
- this.email = email;
- this.password = password;
- }
-
- // _perform_auth_request
- private Dictionary<string, string> PerformAuthRequest(Dictionary<string, string> data)
- {
- NameValueCollection nvc = new NameValueCollection();
- foreach (var kvp in data)
- {
- nvc.Add(kvp.Key.ToString(), kvp.Value.ToString());
- }
- using (WebClient client = new WebClient())
- {
- client.Headers.Add(HttpRequestHeader.UserAgent, userAgent);
- string result;
- try
- {
- byte[] response = client.UploadValues(authUrl, nvc);
- result = Encoding.UTF8.GetString(response);
- }
- catch (WebException e)
- {
- result = new StreamReader(e.Response.GetResponseStream()).ReadToEnd();
- }
- return GoogleKeyUtils.ParseAuthResponse(result);
- }
- }
-
- // perform_master_login
- public Dictionary<string, string> PerformMasterLogin(string service = "ac2dm",
- string deviceCountry = "us", string operatorCountry = "us", string lang = "en", int sdkVersion = 21)
- {
- string signature = GoogleKeyUtils.CreateSignature(email, password, androidKey);
- var dict = new Dictionary<string, string> {
- { "accountType", "HOSTED_OR_GOOGLE" },
- { "Email", email },
- { "has_permission", 1.ToString() },
- { "add_account", 1.ToString() },
- { "EncryptedPasswd", signature},
- { "service", service },
- { "source", "android" },
- { "device_country", deviceCountry },
- { "operatorCountry", operatorCountry },
- { "lang", lang },
- { "sdk_version", sdkVersion.ToString() }
- };
- return PerformAuthRequest(dict);
- }
-
- // perform_oauth
- public Dictionary<string, string> PerformOAuth(string masterToken, string service, string app, string clientSig,
- string deviceCountry = "us", string operatorCountry = "us", string lang = "en", int sdkVersion = 21)
- {
- var dict = new Dictionary<string, string> {
- { "accountType", "HOSTED_OR_GOOGLE" },
- { "Email", email },
- { "has_permission", 1.ToString() },
- { "EncryptedPasswd", masterToken},
- { "service", service },
- { "source", "android" },
- { "app", app },
- { "client_sig", clientSig },
- { "device_country", deviceCountry },
- { "operatorCountry", operatorCountry },
- { "lang", lang },
- { "sdk_version", sdkVersion.ToString() }
- };
- return PerformAuthRequest(dict);
- }
- }
-
- // gpsoauth:google.py
- // URL: https://github.com/simon-weber/gpsoauth/blob/master/gpsoauth/google.py
- class GoogleKeyUtils
- {
- // key_from_b64
- // BitConverter has different endianness, hence the Reverse()
- public static RSAParameters KeyFromB64(string b64Key)
- {
- byte[] decoded = Convert.FromBase64String(b64Key);
- int modLength = BitConverter.ToInt32(decoded.Take(4).Reverse().ToArray(), 0);
- byte[] mod = decoded.Skip(4).Take(modLength).ToArray();
- int expLength = BitConverter.ToInt32(decoded.Skip(modLength + 4).Take(4).Reverse().ToArray(), 0);
- byte[] exponent = decoded.Skip(modLength + 8).Take(expLength).ToArray();
- RSAParameters rsaKeyInfo = new RSAParameters();
- rsaKeyInfo.Modulus = mod;
- rsaKeyInfo.Exponent = exponent;
- return rsaKeyInfo;
- }
-
- // key_to_struct
- // Python version returns a string, but we use byte[] to get the same results
- public static byte[] KeyToStruct(RSAParameters key)
- {
- byte[] modLength = { 0x00, 0x00, 0x00, 0x80 };
- byte[] mod = key.Modulus;
- byte[] expLength = { 0x00, 0x00, 0x00, 0x03 };
- byte[] exponent = key.Exponent;
- return DataTypeUtils.CombineBytes(modLength, mod, expLength, exponent);
- }
-
- // parse_auth_response
- public static Dictionary<string, string> ParseAuthResponse(string text)
- {
- Dictionary<string, string> responseData = new Dictionary<string, string>();
- foreach (string line in text.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
- {
- string[] parts = line.Split('=');
- responseData.Add(parts[0], parts[1]);
- }
- return responseData;
- }
-
- // signature
- public static string CreateSignature(string email, string password, RSAParameters key)
- {
- RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
- rsa.ImportParameters(key);
- SHA1 sha1 = SHA1.Create();
- byte[] prefix = { 0x00 };
- byte[] hash = sha1.ComputeHash(GoogleKeyUtils.KeyToStruct(key)).Take(4).ToArray();
- byte[] encrypted = rsa.Encrypt(Encoding.UTF8.GetBytes(email + "\x00" + password), true);
- return DataTypeUtils.UrlSafeBase64(DataTypeUtils.CombineBytes(prefix, hash, encrypted));
- }
- }
-
- class DataTypeUtils
- {
- public static string UrlSafeBase64(byte[] byteArray)
- {
- return Convert.ToBase64String(byteArray).Replace('+', '-').Replace('/', '_');
- }
-
- public static byte[] CombineBytes(params byte[][] arrays)
- {
- byte[] rv = new byte[arrays.Sum(a => a.Length)];
- int offset = 0;
- foreach (byte[] array in arrays)
- {
- Buffer.BlockCopy(array, 0, rv, offset, array.Length);
- offset += array.Length;
- }
- return rv;
- }
- }
-}
diff --git a/PokemonGo/RocketAPI/Helpers/JsonHelper.cs b/PokemonGo/RocketAPI/Helpers/JsonHelper.cs
deleted file mode 100644
index 2dd2fcd..0000000
--- a/PokemonGo/RocketAPI/Helpers/JsonHelper.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-#region
-
-using Newtonsoft.Json.Linq;
-
-#endregion
-
-namespace PokemonGo.RocketAPI.Helpers
-{
- public class JsonHelper
- {
- public static string GetValue(string json, string key)
- {
- var jObject = JObject.Parse(json);
- return jObject[key].ToString();
- }
- }
-}
\ No newline at end of file
diff --git a/PokemonGo/RocketAPI/Login/GoogleLogin.cs b/PokemonGo/RocketAPI/Login/GoogleLogin.cs
index c91f726..10c9c70 100644
--- a/PokemonGo/RocketAPI/Login/GoogleLogin.cs
+++ b/PokemonGo/RocketAPI/Login/GoogleLogin.cs
@@ -1,115 +1,180 @@
-#region
-
+using PokemonGo.RocketAPI.Exceptions;
using System;
using System.Collections.Generic;
-using System.Diagnostics;
-using System.Threading;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Security.Cryptography;
+using System.Text;
using System.Threading.Tasks;
-using System.Windows.Forms;
-using PokemonGo.RocketAPI.Helpers;
-using System.IO;
-
-
-#endregion
namespace PokemonGo.RocketAPI.Login
{
- public static class GoogleLogin
+ public class GoogleLogin : ILoginType
{
- private const string OauthTokenEndpoint = "https://www.googleapis.com/oauth2/v4/token";
- private const string OauthEndpoint = "https://accounts.google.com/o/oauth2/device/code";
- private const string ClientId = "848232511240-73ri3t7plvk96pj4f85uj8otdat2alem.apps.googleusercontent.com";
- private const string ClientSecret = "NCjF1TLi2CcY6t5mt0ZveuL7";
-
- /// <summary>
- /// Gets the access token from Google
- /// </summary>
- /// <param name="deviceCode"></param>
- /// <returns>tokenResponse</returns>
- public static async Task<TokenResponseModel> GetAccessToken(DeviceCodeModel deviceCode)
- {
- //Poll until user submitted code..
- TokenResponseModel tokenResponse;
- do
- {
- await Task.Delay(2000);
- tokenResponse = await PollSubmittedToken(deviceCode.device_code);
- } while (tokenResponse.access_token == null || tokenResponse.refresh_token == null);
+ private readonly string password;
+ private readonly string email;
- return tokenResponse;
+ public GoogleLogin(string email, string password)
+ {
+ this.email = email;
+ this.password = password;
}
- public static async Task<TokenResponseModel> GetAccessToken(string refreshToken)
+ public async Task<string> GetAccessToken()
{
- return await HttpClientHelper.PostFormEncodedAsync<TokenResponseModel>(OauthTokenEndpoint,
- new KeyValuePair<string, string>("access_type", "offline"),
- new KeyValuePair<string, string>("client_id", ClientId),
- new KeyValuePair<string, string>("client_secret", ClientSecret),
- new KeyValuePair<string, string>("refresh_token", refreshToken),
- new KeyValuePair<string, string>("grant_type", "refresh_token"),
- new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));
+ var _GPSOresponse = await PerformMasterLoginAsync(email, password).ConfigureAwait(false);
+ string token;
+ if (!_GPSOresponse.TryGetValue("Token", out token))
+ throw new LoginFailedException();
+
+ var oauthResponse = await PerformOAuthAsync(
+ token,
+ "audience:server:client_id:848232511240-7so421jotr2609rmqakceuu1luuq0ptb.apps.googleusercontent.com",
+ "com.nianticlabs.pokemongo",
+ "321187995bc7cdc2b5fc91b11a96e2baa8602c62",
+ email).ConfigureAwait(false);
+ return oauthResponse["Auth"];
}
- public static async Task<DeviceCodeModel> GetDeviceCode()
- {
- var deviceCode = await HttpClientHelper.PostFormEncodedAsync<DeviceCodeModel>(OauthEndpoint,
- new KeyValuePair<string, string>("client_id", ClientId),
- new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));
+ private static string b64Key = "AAAAgMom/1a/v0lblO2Ubrt60J2gcuXSljGFQXgcyZWveWLEwo6prwgi3" +
+ "iJIZdodyhKZQrNWp5nKJ3srRXcUW+F1BD3baEVGcmEgqaLZUNBjm057pK" +
+ "RI16kB0YppeGx5qIQ5QjKzsR8ETQbKLNWgRY0QRNVz34kMJR3P/LgHax/" +
+ "6rmf5AAAAAwEAAQ==";
+
+ private static RSAParameters androidKey = GoogleKeyUtils.KeyFromB64(b64Key);
- try
+ private static string version = "0.0.5";
+ private static string authUrl = "https://android.clients.google.com/auth";
+ private static string userAgent = "GPSOAuthSharp/" + version;
+
+ private async static Task<IDictionary<string, string>> PerformAuthRequestAsync(IDictionary<string, string> data)
+ {
+ var handler = new HttpClientHandler
{
- //ColoredConsoleWrite("Google Device Code copied to clipboard");
- System.Console.WriteLine($"Goto: http://www.google.com/device & enter {deviceCode.user_code}");
- File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + @"\Logs.txt", "[" + DateTime.Now.ToString("HH:mm:ss tt") + $"] Goto: http://www.google.com/device & enter {deviceCode.user_code}");
- Process.Start(@"http://www.google.com/device");
- var thread = new Thread(() => Clipboard.SetText(deviceCode.user_code)); //Copy device code
- thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
- thread.Start();
- thread.Join();
- }
- catch (Exception)
+ AutomaticDecompression = DecompressionMethods.GZip,
+ AllowAutoRedirect = false
+ };
+ using (var tempHttpClient = new HttpClient(handler))
{
- //System.Console.WriteLine("Couldnt copy to clipboard, do it manually");
- //System.Console.WriteLine($"Goto: http://www.google.com/device & enter {deviceCode.user_code}");
+ tempHttpClient.DefaultRequestHeaders.UserAgent.ParseAdd(userAgent);
+
+ HttpResponseMessage response;
+ using (var formUrlEncodedContent = new FormUrlEncodedContent(data))
+ {
+ response = await tempHttpClient.PostAsync(authUrl, formUrlEncodedContent).ConfigureAwait(false);
+ }
+
+ var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
+ return GoogleKeyUtils.ParseAuthResponse(content);
}
+ }
- return deviceCode;
+ private static IDictionary<string, string> GenerateBaseRequest(string email, string encryptedPassword, string service)
+ => new Dictionary<string, string> {
+ { "accountType", "HOSTED_OR_GOOGLE" },
+ { "Email", email },
+ { "has_permission", "1" },
+ { "EncryptedPasswd", encryptedPassword},
+ { "service", service },
+ { "source", "android" },
+ { "device_country", "us" },
+ { "operatorCountry", "us" },
+ { "lang", "en" },
+ { "sdk_version", "21" }
+ };
+
+ private static Task<IDictionary<string, string>> PerformMasterLoginAsync(string email, string password)
+ {
+ var signature = GoogleKeyUtils.CreateSignature(email, password, androidKey);
+ var request = GenerateBaseRequest(email, signature, "ac2dm");
+ request.Add("add_account", "1");
+ return PerformAuthRequestAsync(request);
}
- private static async Task<TokenResponseModel> PollSubmittedToken(string deviceCode)
+ private static Task<IDictionary<string, string>> PerformOAuthAsync(string masterToken, string service, string app, string clientSig, string email)
{
- return await HttpClientHelper.PostFormEncodedAsync<TokenResponseModel>(OauthTokenEndpoint,
- new KeyValuePair<string, string>("client_id", ClientId),
- new KeyValuePair<string, string>("client_secret", ClientSecret),
- new KeyValuePair<string, string>("code", deviceCode),
- new KeyValuePair<string, string>("grant_type", "http://oauth.net/grant_type/device/1.0"),
- new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));
+ var request = GenerateBaseRequest(email, masterToken, service);
+ request.Add("app", app);
+ request.Add("client_sig", clientSig);
+ return PerformAuthRequestAsync(request);
}
+ }
+ internal class GoogleKeyUtils
+ {
+ // key_from_b64
+ // BitConverter has different endianness, hence the Reverse()
+ public static RSAParameters KeyFromB64(string b64Key)
+ {
+ var decoded = Convert.FromBase64String(b64Key);
+ var modLength = BitConverter.ToInt32(decoded.Take(4).Reverse().ToArray(), 0);
+ var mod = decoded.Skip(4).Take(modLength).ToArray();
+ var expLength = BitConverter.ToInt32(decoded.Skip(modLength + 4).Take(4).Reverse().ToArray(), 0);
+ var exponent = decoded.Skip(modLength + 8).Take(expLength).ToArray();
+ var rsaKeyInfo = new RSAParameters
+ {
+ Modulus = mod,
+ Exponent = exponent
+ };
+ return rsaKeyInfo;
+ }
- internal class ErrorResponseModel
+ // key_to_struct
+ // Python version returns a string, but we use byte[] to get the same results
+ public static byte[] KeyToStruct(RSAParameters key)
{
- public string error { get; set; }
- public string error_description { get; set; }
+ byte[] modLength = { 0x00, 0x00, 0x00, 0x80 };
+ var mod = key.Modulus;
+ byte[] expLength = { 0x00, 0x00, 0x00, 0x03 };
+ var exponent = key.Exponent;
+ return DataTypeUtils.CombineBytes(modLength, mod, expLength, exponent);
}
- public class TokenResponseModel
+ // parse_auth_response
+ public static Dictionary<string, string> ParseAuthResponse(string text)
{
- public string access_token { get; set; }
- public string token_type { get; set; }
- public int expires_in { get; set; }
- public string refresh_token { get; set; }
- public string id_token { get; set; }
+ var responseData = new Dictionary<string, string>();
+ foreach (string line in text.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
+ {
+ var parts = line.Split('=');
+ responseData.Add(parts[0], parts[1]);
+ }
+ return responseData;
}
+ // signature
+ public static string CreateSignature(string email, string password, RSAParameters key)
+ {
+ using (var rsa = new RSACryptoServiceProvider())
+ {
+ rsa.ImportParameters(key);
+ var sha1 = SHA1.Create();
+ byte[] prefix = { 0x00 };
+ var hash = sha1.ComputeHash(GoogleKeyUtils.KeyToStruct(key)).Take(4).ToArray();
+ var encrypted = rsa.Encrypt(Encoding.UTF8.GetBytes(email + "\x00" + password), true);
+ return DataTypeUtils.UrlSafeBase64(DataTypeUtils.CombineBytes(prefix, hash, encrypted));
+ }
+ }
- public class DeviceCodeModel
+ private class DataTypeUtils
{
- public string verification_url { get; set; }
- public int expires_in { get; set; }
- public int interval { get; set; }
- public string device_code { get; set; }
- public string user_code { get; set; }
+ public static string UrlSafeBase64(byte[] byteArray)
+ {
+ return Convert.ToBase64String(byteArray).Replace('+', '-').Replace('/', '_');
+ }
+
+ public static byte[] CombineBytes(params byte[][] arrays)
+ {
+ var rv = new byte[arrays.Sum(a => a.Length)];
+ var offset = 0;
+ foreach (byte[] array in arrays)
+ {
+ Buffer.BlockCopy(array, 0, rv, offset, array.Length);
+ offset += array.Length;
+ }
+ return rv;
+ }
}
}
}
\ No newline at end of file
diff --git a/PokemonGo/RocketAPI/Login/ILoginType.cs b/PokemonGo/RocketAPI/Login/ILoginType.cs
new file mode 100644
index 0000000..0c102a0
--- /dev/null
+++ b/PokemonGo/RocketAPI/Login/ILoginType.cs
@@ -0,0 +1,16 @@
+using System.Threading.Tasks;
+
+namespace PokemonGo.RocketAPI.Login
+{
+ /// <summary>
+ /// Interface for the login into the game using either Google or PTC
+ /// </summary>
+ interface ILoginType
+ {
+ /// <summary>
+ /// Gets the access token.
+ /// </summary>
+ /// <returns></returns>
+ Task<string> GetAccessToken();
+ }
+}
\ No newline at end of file
diff --git a/PokemonGo/RocketAPI/Login/PtcLogin.cs b/PokemonGo/RocketAPI/Login/PtcLogin.cs
index 7a3c900..0cf6b04 100644
--- a/PokemonGo/RocketAPI/Login/PtcLogin.cs
+++ b/PokemonGo/RocketAPI/Login/PtcLogin.cs
@@ -1,20 +1,24 @@
-#region
-
+using Newtonsoft.Json;
+using PokemonGo.RocketAPI.Exceptions;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
-using PokemonGo.RocketAPI.Exceptions;
-using PokemonGo.RocketAPI.Helpers;
-
-#endregion
namespace PokemonGo.RocketAPI.Login
{
- internal static class PtcLogin
+ class PtcLogin : ILoginType
{
- public static async Task<string> GetAccessToken(string username, string password)
+ readonly string password;
+ readonly string username;
+
+ public PtcLogin(string username, string password)
+ {
+ this.username = username;
+ this.password = password;
+ }
+ public async Task<string> GetAccessToken()
{
var handler = new HttpClientHandler
{
@@ -25,44 +29,88 @@ namespace PokemonGo.RocketAPI.Login
using (var tempHttpClient = new HttpClient(handler))
{
//Get session cookie
- var sessionResp = await tempHttpClient.GetAsync(Resources.PtcLoginUrl);
- var data = await sessionResp.Content.ReadAsStringAsync();
- var lt = JsonHelper.GetValue(data, "lt");
- var executionId = JsonHelper.GetValue(data, "execution");
+ var sessionData = await GetSessionCookie(tempHttpClient).ConfigureAwait(false);
//Login
- var loginResp = await tempHttpClient.PostAsync(Resources.PtcLoginUrl,
- new FormUrlEncodedContent(
- new[]
- {
- new KeyValuePair<string, string>("lt", lt),
- new KeyValuePair<string, string>("execution", executionId),
- new KeyValuePair<string, string>("_eventId", "submit"),
- new KeyValuePair<string, string>("username", username),
- new KeyValuePair<string, string>("password", password)
- }));
-
- var ticketId = HttpUtility.ParseQueryString(loginResp.Headers.Location.Query)["ticket"];
- if (ticketId == null)
- throw new PtcOfflineException();
-
- //Get tokenvar
- var tokenResp = await tempHttpClient.PostAsync(Resources.PtcLoginOauth,
- new FormUrlEncodedContent(
- new[]
- {
- new KeyValuePair<string, string>("client_id", "mobile-app_pokemon-go"),
- new KeyValuePair<string, string>("redirect_uri",
- "https://www.nianticlabs.com/pokemongo/error"),
- new KeyValuePair<string, string>("client_secret",
- "w8ScCUXJQc6kXKw8FiOhd8Fixzht18Dq3PEVkUCP5ZPxtgyWsbTvWHFLm2wNY0JR"),
- new KeyValuePair<string, string>("grant_type", "refresh_token"),
- new KeyValuePair<string, string>("code", ticketId)
- }));
-
- var tokenData = await tokenResp.Content.ReadAsStringAsync();
- return HttpUtility.ParseQueryString(tokenData)["access_token"];
+ var ticketId = await GetLoginTicket(username, password, tempHttpClient, sessionData).ConfigureAwait(false);
+
+ //Get tokenvar
+ return await GetToken(tempHttpClient, ticketId).ConfigureAwait(false);
+ }
+ }
+
+ private static string ExtracktTicketFromResponse(HttpResponseMessage loginResp)
+ {
+ var location = loginResp.Headers.Location;
+ if (location == null)
+ throw new LoginFailedException();
+
+ var ticketId = HttpUtility.ParseQueryString(location.Query)["ticket"];
+
+ if (ticketId == null)
+ throw new PtcOfflineException();
+
+ return ticketId;
+ }
+
+ private static IDictionary<string, string> GenerateLoginRequest(SessionData sessionData, string user, string pass)
+ => new Dictionary<string, string>
+ {
+ { "lt", sessionData.Lt },
+ { "execution", sessionData.Execution },
+ { "_eventId", "submit" },
+ { "username", user },
+ { "password", pass }
+ };
+
+ private static IDictionary<string, string> GenerateTokenVarRequest(string ticketId)
+ => new Dictionary<string, string>
+ {
+ {"client_id", "mobile-app_pokemon-go"},
+ {"redirect_uri", "https://www.nianticlabs.com/pokemongo/error"},
+ {"client_secret", "w8ScCUXJQc6kXKw8FiOhd8Fixzht18Dq3PEVkUCP5ZPxtgyWsbTvWHFLm2wNY0JR"},
+ {"grant_type", "refresh_token"},
+ {"code", ticketId}
+ };
+
+ private static async Task<string> GetLoginTicket(string username, string password, HttpClient tempHttpClient, SessionData sessionData)
+ {
+ HttpResponseMessage loginResp;
+ var loginRequest = GenerateLoginRequest(sessionData, username, password);
+ using (var formUrlEncodedContent = new FormUrlEncodedContent(loginRequest))
+ {
+ loginResp = await tempHttpClient.PostAsync(Resources.PtcLoginUrl, formUrlEncodedContent).ConfigureAwait(false);
}
+
+ var ticketId = ExtracktTicketFromResponse(loginResp);
+ return ticketId;
+ }
+
+ private static async Task<SessionData> GetSessionCookie(HttpClient tempHttpClient)
+ {
+ var sessionResp = await tempHttpClient.GetAsync(Resources.PtcLoginUrl).ConfigureAwait(false);
+ var data = await sessionResp.Content.ReadAsStringAsync().ConfigureAwait(false);
+ var sessionData = JsonConvert.DeserializeObject<SessionData>(data);
+ return sessionData;
+ }
+
+ private static async Task<string> GetToken(HttpClient tempHttpClient, string ticketId)
+ {
+ HttpResponseMessage tokenResp;
+ var tokenRequest = GenerateTokenVarRequest(ticketId);
+ using (var formUrlEncodedContent = new FormUrlEncodedContent(tokenRequest))
+ {
+ tokenResp = await tempHttpClient.PostAsync(Resources.PtcLoginOauth, formUrlEncodedContent).ConfigureAwait(false);
+ }
+
+ var tokenData = await tokenResp.Content.ReadAsStringAsync().ConfigureAwait(false);
+ return HttpUtility.ParseQueryString(tokenData)["access_token"];
+ }
+
+ private class SessionData
+ {
+ public string Lt { get; set; }
+ public string Execution { get; set; }
}
}
-}
+}
\ No newline at end of file
diff --git a/PokemonGo/RocketAPI/PokemonGo.RocketAPI.csproj b/PokemonGo/RocketAPI/PokemonGo.RocketAPI.csproj
index abde253..2b93397 100644
--- a/PokemonGo/RocketAPI/PokemonGo.RocketAPI.csproj
+++ b/PokemonGo/RocketAPI/PokemonGo.RocketAPI.csproj
@@ -71,21 +71,21 @@
<Compile Include="Enums\AuthType.cs" />
<Compile Include="Enums\MiscEnums.cs" />
<Compile Include="Enums\RequestType.cs" />
+ <Compile Include="Exceptions\LoginFailedException.cs" />
<Compile Include="Exceptions\PtcOfflineException.cs" />
<Compile Include="Extensions\DateTimeExtensions.cs" />
<Compile Include="GeneratedCode\AllEnum.cs" />
<Compile Include="GeneratedCode\Payloads.cs" />
<Compile Include="GeneratedCode\Request.cs" />
<Compile Include="GeneratedCode\Response.cs" />
- <Compile Include="GPSOAuthSharp.cs" />
<Compile Include="Helpers\HttpClientHelper.cs" />
- <Compile Include="Helpers\JsonHelper.cs" />
<Compile Include="Helpers\ProtoHelper.cs" />
<Compile Include="Helpers\RetryHandler.cs" />
<Compile Include="Helpers\S2Helper.cs" />
<Compile Include="Helpers\Utils.cs" />
<Compile Include="ISettings.cs" />
<Compile Include="Login\GoogleLogin.cs" />
+ <Compile Include="Login\ILoginType.cs" />
<Compile Include="Login\PtcLogin.cs" />
<None Include="app.config" />
<Compile Include="Client.cs" />
diff --git a/PokemonGo/RocketAPI/Window/MainForm.Designer.cs b/PokemonGo/RocketAPI/Window/MainForm.Designer.cs
index a41b76d..2c3859c 100644
--- a/PokemonGo/RocketAPI/Window/MainForm.Designer.cs
+++ b/PokemonGo/RocketAPI/Window/MainForm.Designer.cs
@@ -33,7 +33,7 @@
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.statusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
- this.startBotToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.startStopBotToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.todoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.pokemonToolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem();
@@ -79,7 +79,7 @@
// menuStrip1
//
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.startBotToolStripMenuItem,
+ this.startStopBotToolStripMenuItem,
this.mapToolStripMenuItem,
this.todoToolStripMenuItem,
this.pokemonToolStripMenuItem2,
@@ -93,10 +93,10 @@
//
// startBotToolStripMenuItem
//
- this.startBotToolStripMenuItem.Name = "startBotToolStripMenuItem";
- this.startBotToolStripMenuItem.Size = new System.Drawing.Size(64, 20);
- this.startBotToolStripMenuItem.Text = "Start Bot";
- this.startBotToolStripMenuItem.Click += new System.EventHandler(this.startBotToolStripMenuItem_Click);
+ this.startStopBotToolStripMenuItem.Name = "startStopBotToolStripMenuItem";
+ this.startStopBotToolStripMenuItem.Size = new System.Drawing.Size(64, 20);
+ this.startStopBotToolStripMenuItem.Text = "Start Bot";
+ this.startStopBotToolStripMenuItem.Click += new System.EventHandler(this.startStopBotToolStripMenuItem_Click);
//
// mapToolStripMenuItem
//
@@ -173,7 +173,7 @@
private System.Windows.Forms.MenuStrip menuStrip1;
private System.Windows.Forms.ToolStripMenuItem todoToolStripMenuItem;
private System.Windows.Forms.ToolStripStatusLabel statusLabel;
- private System.Windows.Forms.ToolStripMenuItem startBotToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem startStopBotToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem showAllToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem showAllToolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem pokemonToolStripMenuItem2;
diff --git a/PokemonGo/RocketAPI/Window/MainForm.cs b/PokemonGo/RocketAPI/Window/MainForm.cs
index fa85042..5dcef41 100644
--- a/PokemonGo/RocketAPI/Window/MainForm.cs
+++ b/PokemonGo/RocketAPI/Window/MainForm.cs
@@ -38,6 +38,7 @@ namespace PokemonGo.RocketAPI.Window
private static int Currentlevel = -1;
private static int TotalExperience = 0;
private static int TotalPokemon = 0;
+ private static bool Stopping = false;
private static bool ForceUnbanning = false;
private static bool FarmingStops = false;
private static bool FarmingPokemons = false;
@@ -110,6 +111,17 @@ namespace PokemonGo.RocketAPI.Window
}
}
+ public void ConsoleClear()
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new Action(ConsoleClear));
+ return;
+ }
+
+ logTextBox.Clear();
+ }
+
public void SetStatusText(string text)
{
if (InvokeRequired)
@@ -192,15 +204,13 @@ namespace PokemonGo.RocketAPI.Window
{
case AuthType.Ptc:
ColoredConsoleWrite(Color.Green, "Login Type: Pokemon Trainers Club");
- await client.DoPtcLogin(ClientSettings.PtcUsername, ClientSettings.PtcPassword);
break;
case AuthType.Google:
ColoredConsoleWrite(Color.Green, "Login Type: Google");
- await client.DoGoogleLogin(ClientSettings.Email, ClientSettings.Password);
-
break;
}
+ await client.Login();
await client.SetServer();
var profile = await client.GetProfile();
var settings = await client.GetSettings();
@@ -284,22 +294,30 @@ namespace PokemonGo.RocketAPI.Window
await Task.Delay(25);
// await ForceUnban(client);
- ColoredConsoleWrite(Color.Red, $"No nearby useful locations found. Please wait 10 seconds.");
- await Task.Delay(10000);
- CheckVersion();
- Execute();
+ if (!Stopping)
+ {
+ ColoredConsoleWrite(Color.Red, $"No nearby useful locations found. Please wait 10 seconds.");
+ await Task.Delay(10000);
+ CheckVersion();
+ Execute();
+ }
+ else
+ {
+ confirmBotStopped();
+ }
}
- catch (TaskCanceledException) { ColoredConsoleWrite(Color.Red, "Task Canceled Exception - Restarting"); Execute(); }
- catch (UriFormatException) { ColoredConsoleWrite(Color.Red, "System URI Format Exception - Restarting"); Execute(); }
- catch (ArgumentOutOfRangeException) { ColoredConsoleWrite(Color.Red, "ArgumentOutOfRangeException - Restarting"); Execute(); }
- catch (ArgumentNullException) { ColoredConsoleWrite(Color.Red, "Argument Null Refference - Restarting"); Execute(); }
- catch (NullReferenceException) { ColoredConsoleWrite(Color.Red, "Null Refference - Restarting"); Execute(); }
- catch (Exception ex) { ColoredConsoleWrite(Color.Red, ex.ToString()); Execute(); }
+
+ catch (TaskCanceledException) { ColoredConsoleWrite(Color.Red, "Task Canceled Exception - Restarting"); if (!Stopping) { Execute(); } else { confirmBotStopped(); } }
+ catch (UriFormatException) { ColoredConsoleWrite(Color.Red, "System URI Format Exception - Restarting"); if (!Stopping) { Execute(); } else { confirmBotStopped(); } }
+ catch (ArgumentOutOfRangeException) { ColoredConsoleWrite(Color.Red, "ArgumentOutOfRangeException - Restarting"); if (!Stopping) { Execute(); } else { confirmBotStopped(); } }
+ catch (ArgumentNullException) { ColoredConsoleWrite(Color.Red, "Argument Null Refference - Restarting"); if (!Stopping) { Execute(); } else { confirmBotStopped(); } }
+ catch (NullReferenceException) { ColoredConsoleWrite(Color.Red, "Null Refference - Restarting"); if (!Stopping) { Execute(); } else { confirmBotStopped(); } }
+ catch (Exception ex) { ColoredConsoleWrite(Color.Red, ex.ToString()); if (!Stopping) { Execute(); } else { confirmBotStopped(); } }
}
private static string CallAPI(string elem, double lat, double lon)
{
- using (XmlReader reader = XmlReader.Create(@"http://api.geonames.org/findNearby?lat=" + lat + "&lng=" + lon + "&username=demo"))
+ using (XmlReader reader = XmlReader.Create(@"http://api.geonames.org/findNearby?lat=" + lat + "&lng=" + lon + "&username=pokemongobot"))
{
while (reader.Read())
{
@@ -329,6 +347,7 @@ namespace PokemonGo.RocketAPI.Window
}
return "Error";
}
+
private async Task ExecuteCatchAllNearbyPokemons(Client client)
{
var mapObjects = await client.GetMapObjects();
@@ -342,7 +361,7 @@ namespace PokemonGo.RocketAPI.Window
foreach (var pokemon in pokemons)
{
- if (ForceUnbanning)
+ if (ForceUnbanning || Stopping)
break;
FarmingPokemons = true;
@@ -425,11 +444,11 @@ namespace PokemonGo.RocketAPI.Window
}
HashSet<FortData> pokeStopSet = new HashSet<FortData>(pokeStops);
IEnumerable<FortData> nextPokeStopList = null;
- if (!ForceUnbanning)
+ if (!ForceUnbanning && !Stopping)
ColoredConsoleWrite(Color.Cyan, $"Visiting {pokeStops.Count()} PokeStops");
foreach (var pokeStop in pokeStops)
{
- if (ForceUnbanning)
+ if (ForceUnbanning || Stopping)
break;
FarmingStops = true;
@@ -486,7 +505,7 @@ namespace PokemonGo.RocketAPI.Window
private async Task ForceUnban(Client client)
{
- if (!ForceUnbanning)
+ if (!ForceUnbanning && !Stopping)
{
ColoredConsoleWrite(Color.LightGreen, "Waiting for last farming action to be complete...");
ForceUnbanning = true;
@@ -539,7 +558,7 @@ namespace PokemonGo.RocketAPI.Window
}
else
{
- ColoredConsoleWrite(Color.Red, "A force unban attempt is in action... Please wait.");
+ ColoredConsoleWrite(Color.Red, "A action is in play... Please wait.");
}
@@ -835,11 +854,33 @@ namespace PokemonGo.RocketAPI.Window
var inventory = await client.GetInventory();
var stats = inventory.InventoryDelta.InventoryItems.Select(i => i.InventoryItemData?.PlayerStats).ToArray();
var profile = await client.GetProfile();
+ Int16 hoursLeft = 0; Int16 minutesLeft = 0; Int32 secondsLeft = 0; double xpSec = 0;
foreach (var v in stats)
if (v != null)
{
int XpDiff = GetXpDiff(client, v.Level);
- SetStatusText(string.Format(Username + " | Level: {0:0} - ({2:0} / {3:0}) | Runtime {1} | Stardust: {4:0}", v.Level, _getSessionRuntimeInTimeFormat(), (v.Experience - v.PrevLevelXp - XpDiff), (v.NextLevelXp - v.PrevLevelXp - XpDiff), profile.Profile.Currency.ToArray()[1].Amount) + " | XP/Hour: " + Math.Round(TotalExperience / GetRuntime()) + " | Pokemon/Hour: " + Math.Round(TotalPokemon / GetRuntime()));
+ //Calculating the exp needed to level up
+ Single expNextLvl = (v.NextLevelXp - v.Experience);
+ //Calculating the exp made per second
+ xpSec = (Math.Round(TotalExperience / GetRuntime()) / 60) / 60;
+ //Calculating the seconds left to level up
+ if(xpSec!=0)
+ secondsLeft = Convert.ToInt32((expNextLvl / xpSec));
+ //formatting data to make an output like DateFormat
+ while (secondsLeft > 60)
+ {
+ secondsLeft -= 60;
+ if (minutesLeft < 60)
+ {
+ minutesLeft++;
+ }
+ else
+ {
+ minutesLeft = 0;
+ hoursLeft++;
+ }
+ }
+ SetStatusText(string.Format(Username + " | Level: {0:0} - ({2:0} / {3:0}) | Runtime {1} | Stardust: {4:0}", v.Level, _getSessionRuntimeInTimeFormat(), (v.Experience - v.PrevLevelXp - XpDiff), (v.NextLevelXp - v.PrevLevelXp - XpDiff), profile.Profile.Currency.ToArray()[1].Amount) + " | XP/Hour: " + Math.Round(TotalExperience / GetRuntime()) + " | Pokemon/Hour: " + Math.Round(TotalPokemon / GetRuntime())+ " | NextLevel in: " + hoursLeft + ":" + minutesLeft + ":" + secondsLeft);
}
await Task.Delay(1000);
ConsoleLevelTitle(Username, client);
@@ -933,6 +974,15 @@ namespace PokemonGo.RocketAPI.Window
return 0;
}
+ public void confirmBotStopped()
+ {
+ //ConsoleClear(); // dont really want the console to be wipped on bot stop, unnecessary
+ ColoredConsoleWrite(Color.Red, $"Bot successfully stopped.");
+ startStopBotToolStripMenuItem.Text = "Start Bot";
+ Stopping = false;
+ bot_started = false;
+ }
+
private void logTextBox_TextChanged(object sender, EventArgs e)
{
logTextBox.SelectionStart = logTextBox.Text.Length;
@@ -945,26 +995,41 @@ namespace PokemonGo.RocketAPI.Window
settingsForm.Show();
}
- private void startBotToolStripMenuItem_Click(object sender, EventArgs e)
+ private static bool bot_started = false;
+ private void startStopBotToolStripMenuItem_Click(object sender, EventArgs e)
{
- startBotToolStripMenuItem.Enabled = false;
- Task.Run(() =>
+ if (!bot_started)
{
- try
+ bot_started = true;
+ startStopBotToolStripMenuItem.Text = "Stop Bot";
+ Task.Run(() =>
{
- //ColoredConsoleWrite(ConsoleColor.White, "Coded by Ferox - edited by NecronomiconCoding");
- CheckVersion();
- Execute();
- }
- catch (PtcOfflineException)
+ try
+ {
+ //ColoredConsoleWrite(ConsoleColor.White, "Coded by Ferox - edited by NecronomiconCoding");
+ CheckVersion();
+ Execute();
+ }
+ catch (PtcOfflineException)
+ {
+ ColoredConsoleWrite(Color.Red, "PTC Servers are probably down OR your credentials are wrong. Try google");
+ }
+ catch (Exception ex)
+ {
+ ColoredConsoleWrite(Color.Red, $"Unhandled exception: {ex}");
+ }
+ });
+ } else
+ {
+ if (!ForceUnbanning)
{
- ColoredConsoleWrite(Color.Red, "PTC Servers are probably down OR your credentials are wrong. Try google");
- }
- catch (Exception ex)
+ Stopping = true;
+ ColoredConsoleWrite(Color.Red, $"Stopping the bot.. Waiting for the last action to be complete.");
+ } else
{
- ColoredConsoleWrite(Color.Red, $"Unhandled exception: {ex}");
+ ColoredConsoleWrite(Color.Red, $"An action is in play, please wait until it's done.");
}
- });
+ }
}
private void showAllToolStripMenuItem3_Click(object sender, EventArgs e)
diff --git a/PokemonGo/RocketAPI/Window/PokeUi.cs b/PokemonGo/RocketAPI/Window/PokeUi.cs
index 3ee7962..114ce62 100644
--- a/PokemonGo/RocketAPI/Window/PokeUi.cs
+++ b/PokemonGo/RocketAPI/Window/PokeUi.cs
@@ -38,15 +38,7 @@ namespace PokemonGo.RocketAPI.Window
try
{
- switch (ClientSettings.AuthType)
- {
- case AuthType.Ptc:
- await client.DoPtcLogin(ClientSettings.PtcUsername, ClientSettings.PtcPassword);
- break;
- case AuthType.Google:
- await client.DoGoogleLogin(ClientSettings.Email, ClientSettings.Password);
- break;
- }
+ await client.Login();
await client.SetServer();
var profile = await client.GetProfile();
var inventory = await client.GetInventory();
diff --git a/PokemonGo/RocketAPI/Window/PokemonForm.cs b/PokemonGo/RocketAPI/Window/PokemonForm.cs
index 6f36da2..90e17bc 100644
--- a/PokemonGo/RocketAPI/Window/PokemonForm.cs
+++ b/PokemonGo/RocketAPI/Window/PokemonForm.cs
@@ -32,22 +32,13 @@ namespace PokemonGo.RocketAPI.Window
try
{
- switch (ClientSettings.AuthType)
- {
- case AuthType.Ptc:
- await client.DoPtcLogin(ClientSettings.PtcUsername, ClientSettings.PtcPassword);
- break;
- case AuthType.Google:
- await client.DoGoogleLogin(ClientSettings.Email, ClientSettings.Password);
- break;
- }
-
+ await client.Login();
await client.SetServer();
var inventory = await client.GetInventory();
var pokemons =
inventory.InventoryDelta.InventoryItems.Select(i => i.InventoryItemData?.Pokemon)
.Where(p => p != null && p?.PokemonId > 0).OrderByDescending(key => key.Cp);
-
+
foreach (var pokemon in pokemons)
{
diff --git a/PokemonGo/RocketAPI/Window/Properties/AssemblyInfo.cs b/PokemonGo/RocketAPI/Window/Properties/AssemblyInfo.cs
index 3402d68..754dab1 100644
--- a/PokemonGo/RocketAPI/Window/Properties/AssemblyInfo.cs
+++ b/PokemonGo/RocketAPI/Window/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.7.0.1")]
+[assembly: AssemblyVersion("1.7.1.1")]
[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/README.md b/README.md
index f396ae3..74a65a8 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,9 @@
# Pokemon-Go-Rocket-API
+# Discusion not controlled by me but by user 1461748123
+* Discord channel for user and developer discussions.
+* https://discord.gg/y6EU2qY
+
#Window


@@ -27,17 +31,27 @@ A Pokémon Go bot in C#
* Logs everything into Logs.txt
## Getting Started
-
-Go to PokemonGo\RocketAPI\Window\App.config -> Edit the Settings you like -> Build and Run (CTRL+F5)
+Build and Run (CTRL+F5)
# Settings
## AuthType
-* *Google* - Google login
-* *Ptc* - Pokémon Trainer Club login with username/password combination
+* *google* - Google login
+* *ptc* - Pokémon Trainer Club
## PtcUsername
-* *username* for PTC account. No need for when using Google.
-* *password* for PTC account. No need for when using Google.
+* *username* - for PTC account. No need for when using Google.
+
+## PtcPassword
+* *password* - for PTC account. No need for when using Google.
+
+## Email
+* *email@gmail.com* - for Google account. No need for when using PTC.
+
+## Password
+* *password* - for Google account. No need for when using PTC.
+
+## GoogleRefreshToken
+* *token* - for Google account. No need for wen using PTC. (Obsolete)
## DefaultLatitude
* *12.345678* - Latitude of your location you want to use the bot in. Number between -90 and +90. Doesn't matter how many numbers stand after the comma.
@@ -68,7 +82,8 @@ Go to PokemonGo\RocketAPI\Window\App.config -> Edit the Settings you like -> Bui
* *probability* - Use RazzBerry when Pokémon catch chance is under a specific percentage.
## RazzBerrySetting
-* *value* - CP: Use RazzBerry when Pokémon is over this value | Probability Mode: Use Razzberry when % of catching is under this value
+* *cp value* - If RazzBerryMode is cp. Use RazzBerry when Pokémon is over this value
+* *probability value* - If RazzBerryMode is probability. Use Razzberry when % of catching is under this value. Between 0 and 1.
## TransferType
* *none* - disables transferring
@@ -80,6 +95,19 @@ Go to PokemonGo\RocketAPI\Window\App.config -> Edit the Settings you like -> Bui
## TransferCPThreshold
* *CP* - transfers all Pokémon with less CP than this value.
+## TransferIVThreshold
+* *IV* - transfers all Pokémon with less IV than this value. Between 0 and 1.
+
+## TravelSpeed
+* *Speed* - Travel speed in km/h
+
+## ImageSize
+* *px* - Pixel size for Pokémon Thumbnails
+
+## CatchPokemon
+* *true* - Catch Pokémon and get Items from PokéStops
+* *false* - Don't catch Pokémon and get Items from PokéStops
+
## EvolveAllGivenPokemons
* *false* - Evolves no Pokémon.
* *true* - Evolves all Pokémon.
\ No newline at end of file
You may download the files in Public Git.