Merge pull request #446 from BahaStriker/master

Detective Squirrel [2016-07-29 09:52:23]
Merge pull request #446 from BahaStriker/master

Fixed Google Login
Filename
PokemonGo/RocketAPI/Client.cs
PokemonGo/RocketAPI/Console/App.config
PokemonGo/RocketAPI/Console/Program.cs
PokemonGo/RocketAPI/Console/Settings.cs
PokemonGo/RocketAPI/Extensions/HttpClientExtensions.cs
PokemonGo/RocketAPI/GPSOAuthSharp.cs
PokemonGo/RocketAPI/ISettings.cs
PokemonGo/RocketAPI/Window/App.config
PokemonGo/RocketAPI/Window/MainForm.cs
PokemonGo/RocketAPI/Window/PokeUi.cs
PokemonGo/RocketAPI/Window/PokemonForm.cs
PokemonGo/RocketAPI/Window/Settings.cs
PokemonGo/RocketAPI/Window/SettingsForm.cs
diff --git a/PokemonGo/RocketAPI/Client.cs b/PokemonGo/RocketAPI/Client.cs
index c3d5094..7e247ea 100644
--- a/PokemonGo/RocketAPI/Client.cs
+++ b/PokemonGo/RocketAPI/Client.cs
@@ -20,6 +20,7 @@ using System.Threading;
 using PokemonGo.RocketAPI.Exceptions;
 using System.Text;
 using System.IO;
+using DankMemes.GPSOAuthSharp;

 #endregion

@@ -85,27 +86,24 @@ namespace PokemonGo.RocketAPI
                         catchPokemonRequest);
         }

-        public async Task DoGoogleLogin()
+        public async Task DoGoogleLogin(string email, string password)
         {
             _authType = AuthType.Google;
-            GoogleLogin.TokenResponseModel tokenResponse = null;
-
-            if (string.IsNullOrEmpty(_settings.GoogleRefreshToken) && string.IsNullOrEmpty(AccessToken))
-            {
-                var deviceCode = await GoogleLogin.GetDeviceCode();
-                tokenResponse = await GoogleLogin.GetAccessToken(deviceCode);
-                _accessToken = tokenResponse.id_token;
-                ColoredConsoleWrite(ConsoleColor.White, $"Put RefreshToken in settings for direct login: {tokenResponse.refresh_token}");
-                _settings.GoogleRefreshToken = tokenResponse.refresh_token;
-                AccessToken = tokenResponse.refresh_token;
-            }
-            else
+            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"))
             {
-                if (!string.IsNullOrEmpty(_settings.GoogleRefreshToken))
-                    tokenResponse = await GoogleLogin.GetAccessToken(_settings.GoogleRefreshToken);
-                else
-                    tokenResponse = await GoogleLogin.GetAccessToken(AccessToken);
-                _accessToken = tokenResponse.id_token;
+                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"];
             }
         }

diff --git a/PokemonGo/RocketAPI/Console/App.config b/PokemonGo/RocketAPI/Console/App.config
index 98a593f..1369910 100644
--- a/PokemonGo/RocketAPI/Console/App.config
+++ b/PokemonGo/RocketAPI/Console/App.config
@@ -15,6 +15,8 @@
     <add key="AuthType" value="Google" /> <!--Google/Ptc-->
     <add key="PtcUsername" value="username" /> <!--Username-->
     <add key="PtcPassword" value="pw" /> <!--Password-->
+    <add key="Email" value="" />
+    <add key="Password" value="" />
     <add key="GoogleRefreshToken" value="" />
     <add key="DefaultLatitude" value="45.030152" /> <!--Default Viaduct Harbour, Auckland, New Zealand-->
     <add key="DefaultLongitude" value="-93.31931" /> <!--Default Viaduct Harbour, Auckland, New Zealand-->
diff --git a/PokemonGo/RocketAPI/Console/Program.cs b/PokemonGo/RocketAPI/Console/Program.cs
index d7fc3e5..1c11260 100644
--- a/PokemonGo/RocketAPI/Console/Program.cs
+++ b/PokemonGo/RocketAPI/Console/Program.cs
@@ -152,7 +152,7 @@ namespace PokemonGo.RocketAPI.Console
                         await client.DoPtcLogin(ClientSettings.PtcUsername, ClientSettings.PtcPassword);
                         break;
                     case AuthType.Google:
-                        await client.DoGoogleLogin();
+                        await client.DoGoogleLogin(ClientSettings.Email, ClientSettings.Password);
                         break;
                 }

@@ -174,6 +174,11 @@ namespace PokemonGo.RocketAPI.Console
                     ColoredConsoleWrite(ConsoleColor.Cyan, "Account: " + ClientSettings.PtcUsername);
                     ColoredConsoleWrite(ConsoleColor.Cyan, "Password: " + ClientSettings.PtcPassword + "\n");
                 }
+                else
+                {
+                    ColoredConsoleWrite(ConsoleColor.Cyan, "Email: " + ClientSettings.Email);
+                    ColoredConsoleWrite(ConsoleColor.Cyan, "Password: " + ClientSettings.Password + "\n");
+                }
                 ColoredConsoleWrite(ConsoleColor.DarkGray, "Name: " + profile.Profile.Username);
                 ColoredConsoleWrite(ConsoleColor.DarkGray, "Team: " + profile.Profile.Team);
                 if (profile.Profile.Currency.ToArray()[0].Amount > 0) // If player has any pokecoins it will show how many they have.
diff --git a/PokemonGo/RocketAPI/Console/Settings.cs b/PokemonGo/RocketAPI/Console/Settings.cs
index 250d797..78dddbb 100644
--- a/PokemonGo/RocketAPI/Console/Settings.cs
+++ b/PokemonGo/RocketAPI/Console/Settings.cs
@@ -28,6 +28,8 @@ namespace PokemonGo.RocketAPI.Console
         public AuthType AuthType => (GetSetting() != string.Empty ? GetSetting() : "Ptc") == "Ptc" ? AuthType.Ptc : AuthType.Google;
         public string PtcUsername => GetSetting() != string.Empty ? GetSetting() : "username";
         public string PtcPassword => GetSetting() != string.Empty ? GetSetting() : "password";
+        public string Email => GetSetting() != string.Empty ? GetSetting() : "Email";
+        public string Password => GetSetting() != string.Empty ? GetSetting() : "Password";

         public double DefaultLatitude
         {
diff --git a/PokemonGo/RocketAPI/Extensions/HttpClientExtensions.cs b/PokemonGo/RocketAPI/Extensions/HttpClientExtensions.cs
index ce6c5d7..81d97cb 100644
--- a/PokemonGo/RocketAPI/Extensions/HttpClientExtensions.cs
+++ b/PokemonGo/RocketAPI/Extensions/HttpClientExtensions.cs
@@ -1,4 +1,4 @@
-#region
+#region

 using System.Net.Http;
 using System.Threading.Tasks;
@@ -28,21 +28,41 @@ namespace PokemonGo.RocketAPI.Extensions
             return decodedResponse;
         }

-        public static async Task<TResponsePayload> PostProtoPayload<TRequest, TResponsePayload>(this HttpClient client,
-            string url, TRequest request) where TRequest : IMessage<TRequest>
-            where TResponsePayload : IMessage<TResponsePayload>, new()
-        {
-      //      ColoredConsoleWrite(ConsoleColor.Red, ($"[DEBUG] [{DateTime.Now.ToString("HH:mm:ss")}] requesting {typeof(TResponsePayload).Name}"));
-            var response = await PostProto(client, url, request);
+   private static bool waitingForResponse = false;
+    public static async Task<TResponsePayload> PostProtoPayload<TRequest, TResponsePayload>(this HttpClient client,
+        string url, TRequest request) where TRequest : IMessage<TRequest>
+        where TResponsePayload : IMessage<TResponsePayload>, new()
+    {
+        ByteString payload = null;

-            //Decode payload
-            //todo: multi-payload support
-            var payload = response.Payload[0];
-            var parsedPayload = new TResponsePayload();
-            parsedPayload.MergeFrom(payload);
+            while (waitingForResponse)
+                await Task.Delay(30);
+            waitingForResponse = true;

-            return parsedPayload;
-        }
+            Response response = null;
+            int count = 0;
+            do
+            {
+                count++;
+                ColoredConsoleWrite(ConsoleColor.Red, "ArgumentOutOfRangeException - Restarting");
+                ColoredConsoleWrite(ConsoleColor.Red, ($"[DEBUG] [{DateTime.Now.ToString("HH:mm:ss")}] requesting {typeof(TResponsePayload).Name}"));
+                response = await PostProto(client, url, request);
+                waitingForResponse = false;
+
+
+
+                //Decode payload
+                //todo: multi-payload support
+
+                await Task.Delay(30);// request every 30ms, up this value for not spam their server
+            } while (response.Payload.Count < 1 && count < 30);
+            payload = response.Payload[0];
+
+        var parsedPayload = new TResponsePayload();
+        parsedPayload.MergeFrom(payload);
+
+        return parsedPayload;
+    }
         public static void ColoredConsoleWrite(ConsoleColor color, string text)
         {
             ConsoleColor originalColor = System.Console.ForegroundColor;
@@ -52,4 +72,4 @@ namespace PokemonGo.RocketAPI.Extensions
         }

     }
-}
\ No newline at end of file
+}
diff --git a/PokemonGo/RocketAPI/GPSOAuthSharp.cs b/PokemonGo/RocketAPI/GPSOAuthSharp.cs
new file mode 100644
index 0000000..9415c32
--- /dev/null
+++ b/PokemonGo/RocketAPI/GPSOAuthSharp.cs
@@ -0,0 +1,177 @@
+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/ISettings.cs b/PokemonGo/RocketAPI/ISettings.cs
index 9fc20db..be51673 100644
--- a/PokemonGo/RocketAPI/ISettings.cs
+++ b/PokemonGo/RocketAPI/ISettings.cs
@@ -18,6 +18,8 @@ namespace PokemonGo.RocketAPI
         string GoogleRefreshToken { get; set; }
         string PtcPassword { get; }
         string PtcUsername { get; }
+        string Email { get;  }
+        string Password { get; }
         bool EvolveAllGivenPokemons { get; }
         string TransferType { get; }
         int TransferCPThreshold { get; }
diff --git a/PokemonGo/RocketAPI/Window/App.config b/PokemonGo/RocketAPI/Window/App.config
index 924e21b..754e03d 100644
--- a/PokemonGo/RocketAPI/Window/App.config
+++ b/PokemonGo/RocketAPI/Window/App.config
@@ -18,6 +18,10 @@
     <!--Username-->
     <add key="PtcPassword" value="" />
     <!--Password-->
+    <add key="Email" value="" />
+    <!--Google E-mail-->
+    <add key="Password" value="" />
+    <!--E-mail Password-->
     <add key="GoogleRefreshToken" value="" />
     <add key="DefaultLatitude" value="-36.714359" />
     <!--Default Viaduct Harbour, Auckland, New Zealand-->
@@ -50,4 +54,4 @@
     <add key="EvolveAllGivenPokemons" value="false" />
     <add key="ClientSettingsProvider.ServiceUri" value="" />
   </appSettings>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/PokemonGo/RocketAPI/Window/MainForm.cs b/PokemonGo/RocketAPI/Window/MainForm.cs
index 6fb4b26..d51c04c 100644
--- a/PokemonGo/RocketAPI/Window/MainForm.cs
+++ b/PokemonGo/RocketAPI/Window/MainForm.cs
@@ -193,10 +193,11 @@ namespace PokemonGo.RocketAPI.Window
                         break;
                     case AuthType.Google:
                         ColoredConsoleWrite(Color.Green, "Login Type: Google");
-                        if (ClientSettings.GoogleRefreshToken == "")
-                            ColoredConsoleWrite(Color.Green, "Now opening www.Google.com/device and copying the 8 digit code to your clipboard");
+                            ColoredConsoleWrite(Color.Green, "Authenticating...\n");
+                            ColoredConsoleWrite(Color.Green, "Logging in to Google account.");
+
+                        await client.DoGoogleLogin(ClientSettings.Email, ClientSettings.Password);

-                        await client.DoGoogleLogin();
                         break;
                 }

@@ -213,11 +214,16 @@ namespace PokemonGo.RocketAPI.Window

                 // Write the players ingame details
                 ColoredConsoleWrite(Color.Yellow, "----------------------------");
-                if (ClientSettings.AuthType == AuthType.Ptc)
-                {
-                    ColoredConsoleWrite(Color.Cyan, "Account: " + ClientSettings.PtcUsername);
-                    ColoredConsoleWrite(Color.Cyan, "Password: " + ClientSettings.PtcPassword + "\n");
-                }
+                        if (ClientSettings.AuthType == AuthType.Ptc)
+                        {
+                            ColoredConsoleWrite(Color.Cyan, "Account: " + ClientSettings.PtcUsername);
+                            ColoredConsoleWrite(Color.Cyan, "Password: " + ClientSettings.PtcPassword + "\n");
+                        }
+                        else
+                        {
+                            ColoredConsoleWrite(Color.Cyan, "Email: " + ClientSettings.Email);
+                            ColoredConsoleWrite(Color.Cyan, "Password: " + ClientSettings.Password + "\n");
+                        }
                 ColoredConsoleWrite(Color.DarkGray, "Name: " + profile.Profile.Username);
                 ColoredConsoleWrite(Color.DarkGray, "Team: " + profile.Profile.Team);
                 if (profile.Profile.Currency.ToArray()[0].Amount > 0) // If player has any pokecoins it will show how many they have.
diff --git a/PokemonGo/RocketAPI/Window/PokeUi.cs b/PokemonGo/RocketAPI/Window/PokeUi.cs
index 1975c4f..0fc992b 100644
--- a/PokemonGo/RocketAPI/Window/PokeUi.cs
+++ b/PokemonGo/RocketAPI/Window/PokeUi.cs
@@ -44,7 +44,7 @@ namespace PokemonGo.RocketAPI.Window
                         await client.DoPtcLogin(ClientSettings.PtcUsername, ClientSettings.PtcPassword);
                         break;
                     case AuthType.Google:
-                        await client.DoGoogleLogin();
+                        await client.DoGoogleLogin(ClientSettings.Email, ClientSettings.Password);
                         break;
                 }
                 //
@@ -306,4 +306,4 @@ namespace PokemonGo.RocketAPI.Window
 			catch (Exception ex) { await PowerUp(pokemon); }
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/PokemonGo/RocketAPI/Window/PokemonForm.cs b/PokemonGo/RocketAPI/Window/PokemonForm.cs
index 89cfe15..6f36da2 100644
--- a/PokemonGo/RocketAPI/Window/PokemonForm.cs
+++ b/PokemonGo/RocketAPI/Window/PokemonForm.cs
@@ -38,7 +38,7 @@ namespace PokemonGo.RocketAPI.Window
                         await client.DoPtcLogin(ClientSettings.PtcUsername, ClientSettings.PtcPassword);
                         break;
                     case AuthType.Google:
-                        await client.DoGoogleLogin();
+                        await client.DoGoogleLogin(ClientSettings.Email, ClientSettings.Password);
                         break;
                 }

diff --git a/PokemonGo/RocketAPI/Window/Settings.cs b/PokemonGo/RocketAPI/Window/Settings.cs
index 75f32f9..949297d 100644
--- a/PokemonGo/RocketAPI/Window/Settings.cs
+++ b/PokemonGo/RocketAPI/Window/Settings.cs
@@ -62,6 +62,8 @@ namespace PokemonGo.RocketAPI.Window

         public string PtcUsername => GetSetting() != string.Empty ? GetSetting() : "username";
         public string PtcPassword => GetSetting() != string.Empty ? GetSetting() : "password";
+        public string Email => GetSetting() != string.Empty ? GetSetting() : "Email";
+        public string Password => GetSetting() != string.Empty ? GetSetting() : "Password";

         public double DefaultLatitude
         {
diff --git a/PokemonGo/RocketAPI/Window/SettingsForm.cs b/PokemonGo/RocketAPI/Window/SettingsForm.cs
index 00b42f7..f086ec7 100644
--- a/PokemonGo/RocketAPI/Window/SettingsForm.cs
+++ b/PokemonGo/RocketAPI/Window/SettingsForm.cs
@@ -23,8 +23,16 @@ namespace PokemonGo.RocketAPI.Window
         private void SettingsForm_Load(object sender, EventArgs e)
         {
             authTypeCb.Text = Settings.Instance.AuthType.ToString();
-            ptcUserText.Text = Settings.Instance.PtcUsername;
-            ptcPassText.Text = Settings.Instance.PtcPassword;
+            if (authTypeCb.Text == "google")
+            {
+                ptcUserText.Text = Settings.Instance.Email;
+                ptcPassText.Text = Settings.Instance.Password;
+            }
+            else
+            {
+                ptcUserText.Text = Settings.Instance.PtcUsername;
+                ptcPassText.Text = Settings.Instance.PtcPassword;
+            }
             latitudeText.Text = Settings.Instance.DefaultLatitude.ToString();
             longitudeText.Text = Settings.Instance.DefaultLongitude.ToString();
             razzmodeCb.Text = Settings.Instance.RazzBerryMode;
@@ -66,8 +74,16 @@ namespace PokemonGo.RocketAPI.Window
         private void saveBtn_Click(object sender, EventArgs e)
         {
             Settings.Instance.SetSetting(authTypeCb.Text, "AuthType");
-            Settings.Instance.SetSetting(ptcUserText.Text, "PtcUsername");
-            Settings.Instance.SetSetting(ptcPassText.Text, "PtcPassword");
+            if (authTypeCb.Text == "google")
+            {
+                Settings.Instance.SetSetting(ptcUserText.Text, "Email");
+                Settings.Instance.SetSetting(ptcPassText.Text, "Password");
+            }
+            else
+            {
+                Settings.Instance.SetSetting(ptcUserText.Text, "PtcUsername");
+                Settings.Instance.SetSetting(ptcPassText.Text, "PtcPassword");
+            }
             Settings.Instance.SetSetting(latitudeText.Text.Replace(',', '.'), "DefaultLatitude");
             Settings.Instance.SetSetting(longitudeText.Text.Replace(',', '.'), "DefaultLongitude");

@@ -93,17 +109,11 @@ namespace PokemonGo.RocketAPI.Window
         {
             if (authTypeCb.Text == "google")
             {
-                ptcUserText.Visible = false;
-                ptcPassText.Visible = false;
-                ptcUserLabel.Visible = false;
-                ptcPasswordLabel.Visible = false;
+                ptcUserLabel.Text = "Email:";
             }
             else
             {
-                ptcUserText.Visible = true;
-                ptcPassText.Visible = true;
-                ptcUserLabel.Visible = true;
-                ptcPasswordLabel.Visible = true;
+                ptcUserLabel.Text = "Username:";

             }
         }
You may download the files in Public Git.