Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Core/LoginWindowState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ enum LoginWindowState
Selection,
Login,
Code,
CodeOption,
Loading,
Success
}
Expand Down
97 changes: 97 additions & 0 deletions Core/WindowUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,18 @@ public static LoginWindowState GetLoginWindowState(WindowHandle loginWindow)
{
return LoginWindowState.Error;
}
else if (inputs.Count == 0 && buttons.Count == 0 && groups.Count == 0 && images.Count == 3 && texts.Count == 7)
{
// Check if "Enter a code instead" text is present
foreach (var text in texts)
{
string content = text.Name;
if (content.Contains("Enter a code instead") || content.Contains("_2YsaRupK3XuabHMh9_BfZP"))
{
return LoginWindowState.CodeOption;
}
}
}
else if (inputs.Count == 0 && images.Count >= 2 && buttons.Count > 0 && texts.Count == 0)
{
return LoginWindowState.Selection;
Expand Down Expand Up @@ -584,5 +596,90 @@ public static IDataObject GetClipboardDataObjectSTA()
thread.Join();
return data;
}

public static LoginWindowState HandleCodeOption(WindowHandle loginWindow)
{
using (var automation = new UIA3Automation())
{
try
{
AutomationElement window = automation.FromHandle(loginWindow.RawPtr);

if (window == null)
{
return LoginWindowState.Invalid;
}

window.Focus();

AutomationElement document = window.FindFirstDescendant(e => e.ByControlType(ControlType.Document));
AutomationElement[] texts = document.FindAllChildren(e => e.ByControlType(ControlType.Text));

// Find and click the "Enter a code instead" text element
foreach (var text in texts)
{
string content = text.Name;
if (content.Contains("Enter a code instead"))
{
// Try to click the text element directly
try
{
text.Focus();
text.Click();
Thread.Sleep(500); // Wait for transition
return LoginWindowState.Code;
}
catch
{
// If direct click fails, try using coordinates
var rect = text.Properties.BoundingRectangle;
if (rect.IsSupported && rect.Value.X > 0)
{
double centerX = rect.Value.X + rect.Value.Width / 2;
double centerY = rect.Value.Y + rect.Value.Height / 2;
Mouse.Click(new System.Drawing.Point((int)centerX, (int)centerY));
Thread.Sleep(500);
return LoginWindowState.Code;
}
}
}
}

// Alternative: try to find clickable elements in the area where "Enter a code instead" appears
AutomationElement[] allElements = document.FindAllDescendants();
foreach (var element in allElements)
{
if (element.Name.Contains("Enter a code instead"))
{
try
{
element.Focus();
element.Click();
Thread.Sleep(500);
return LoginWindowState.Code;
}
catch
{
var rect = element.Properties.BoundingRectangle;
if (rect.IsSupported && rect.Value.X > 0)
{
double centerX = rect.Value.X + rect.Value.Width / 2;
double centerY = rect.Value.Y + rect.Value.Height / 2;
Mouse.Click(new System.Drawing.Point((int)centerX, (int)centerY));
Thread.Sleep(500);
return LoginWindowState.Code;
}
}
}
}
}
catch (Exception e)
{
Console.WriteLine("HandleCodeOption error: " + e.Message);
}
}

return LoginWindowState.CodeOption; // Return same state if click failed
}
}
}
22 changes: 19 additions & 3 deletions Views/AccountsWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1405,7 +1405,7 @@ private void EnterCredentials(Process steamProcess, Account account, int tryCoun
SetWindowTitle("Working");
LoginWindowState state = LoginWindowState.None;

while (state != LoginWindowState.Success && state != LoginWindowState.Code)
while (state != LoginWindowState.Success && state != LoginWindowState.Code && state != LoginWindowState.CodeOption)
{
if (steamProcess.HasExited || state == LoginWindowState.Error)
{
Expand All @@ -1427,6 +1427,14 @@ private void EnterCredentials(Process steamProcess, Account account, int tryCoun
string password = StringCipher.Decrypt(account.Password, eKey);
state = WindowUtils.TryCredentialsEntry(steamLoginWindow, account.Name, password, settings.User.RememberPassword);
}

if (state == LoginWindowState.CodeOption)
{
// Handle "Enter a code instead" option
state = WindowUtils.HandleCodeOption(steamLoginWindow);
// Continue the loop to check if we're now in Code state
continue;
}
}

string secret = StringCipher.Decrypt(account.SharedSecret, eKey);
Expand Down Expand Up @@ -1508,6 +1516,14 @@ private void EnterReact2FA(Process steamProcess, Account account, int tryCount)

state = WindowUtils.GetLoginWindowState(steamLoginWindow);

if (state == LoginWindowState.CodeOption)
{
// Handle "Enter a code instead" option
state = WindowUtils.HandleCodeOption(steamLoginWindow);
// Continue the loop to check if we're now in Code state
continue;
}

if (state == LoginWindowState.Code)
{
state = WindowUtils.TryCodeEntry(steamLoginWindow, secret);
Expand Down Expand Up @@ -2505,8 +2521,6 @@ private void AccountsDataGrid_PreviewMouseRightButtonDown(object sender, MouseBu
}
}

#endregion

private void AccountsDataGrid_ColumnReordered(object sender, DataGridColumnEventArgs e)
{
foreach (DataGridColumn column in AccountsDataGrid.Columns)
Expand Down Expand Up @@ -2682,5 +2696,7 @@ private void ShowMessage(string title, string message)
await this.ShowMessageAsync(title, message);
});
}

#endregion
}
}