Ottimizzazioni UI e performance click handler
- Rimosse righe inutilizzate e semplificato layout in `MainWindow.xaml`. - Aggiunti pulsanti di navigazione accanto alla barra indirizzi. - Convertite operazioni UI in asincrone con `Dispatcher.BeginInvoke`. - Introdotto aggiornamento griglia bidder ogni 2 secondi per ridurre lag. - Migliorata gestione log con `AppendText` e controllo dimensione ottimizzato. - Ridotto polling dinamico per timer bassi (minimo 20ms). - Ottimizzato script di click con cache bottone e timeout ridotto (500ms). - Implementato multi-click parallelo con delay minimo (20ms). - Parsing JSON e lettura impostazioni resi più efficienti. - Rimosso codice obsoleto e semplificata gestione eventi.
This commit is contained in:
@@ -95,11 +95,9 @@
|
|||||||
<RowDefinition Height="Auto" /> <!-- Start -->
|
<RowDefinition Height="Auto" /> <!-- Start -->
|
||||||
<RowDefinition Height="Auto" /> <!-- Pause -->
|
<RowDefinition Height="Auto" /> <!-- Pause -->
|
||||||
<RowDefinition Height="Auto" /> <!-- Stop -->
|
<RowDefinition Height="Auto" /> <!-- Stop -->
|
||||||
<RowDefinition Height="Auto" /> <!-- Back/Refresh/Clear -->
|
|
||||||
<RowDefinition Height="Auto" /> <!-- Stats -->
|
<RowDefinition Height="Auto" /> <!-- Stats -->
|
||||||
<RowDefinition Height="Auto" /> <!-- Settings Row 1 -->
|
<RowDefinition Height="Auto" /> <!-- Settings Row 1 -->
|
||||||
<RowDefinition Height="Auto" /> <!-- Settings Row 2 -->
|
<RowDefinition Height="Auto" /> <!-- Settings Row 2 -->
|
||||||
<RowDefinition Height="Auto" /> <!-- Advanced timing control -->
|
|
||||||
<RowDefinition Height="Auto" /> <!-- Bidders label with clear button -->
|
<RowDefinition Height="Auto" /> <!-- Bidders label with clear button -->
|
||||||
<RowDefinition Height="Auto" /> <!-- Bidders grid -->
|
<RowDefinition Height="Auto" /> <!-- Bidders grid -->
|
||||||
<RowDefinition Height="Auto" /> <!-- Log label with clear button -->
|
<RowDefinition Height="Auto" /> <!-- Log label with clear button -->
|
||||||
@@ -112,23 +110,8 @@
|
|||||||
|
|
||||||
<Button x:Name="StopButton" Grid.Row="2" Style="{StaticResource StopButtonStyle}" Click="StopButton_Click" IsEnabled="False" Margin="12,6,12,0">Stop</Button>
|
<Button x:Name="StopButton" Grid.Row="2" Style="{StaticResource StopButtonStyle}" Click="StopButton_Click" IsEnabled="False" Margin="12,6,12,0">Stop</Button>
|
||||||
|
|
||||||
<!-- Back / Refresh / ClearStats on same line -->
|
|
||||||
<Grid Grid.Row="3" Margin="12,6,12,0">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
<ColumnDefinition Width="8" />
|
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
<ColumnDefinition Width="8" />
|
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
|
|
||||||
<Button x:Name="BackButton" Grid.Column="0" Style="{StaticResource RefreshButtonStyle}" Click="BackButton_Click" Height="36">Indietro</Button>
|
|
||||||
<Button x:Name="RefreshButton" Grid.Column="2" Style="{StaticResource RefreshButtonStyle}" Click="RefreshButton_Click" Height="36">Aggiorna</Button>
|
|
||||||
<Button x:Name="ClearStatsButton" Grid.Column="4" Style="{StaticResource RefreshButtonStyle}" Click="ClearStatsButton_Click" Height="36">Pulisci</Button>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<!-- Stats con prezzo corrente e Multi-Click -->
|
<!-- Stats con prezzo corrente e Multi-Click -->
|
||||||
<Grid Grid.Row="4" Margin="12,8,12,0">
|
<Grid Grid.Row="3" Margin="12,8,12,0">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
@@ -156,7 +139,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<!-- Settings Row 1: Max Clicks, Max Resets, Min Price, Max Price -->
|
<!-- Settings Row 1: Max Clicks, Max Resets, Min Price, Max Price -->
|
||||||
<Grid Grid.Row="5" Margin="12,8,12,0">
|
<Grid Grid.Row="4" Margin="12,8,12,0">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="8" />
|
<ColumnDefinition Width="8" />
|
||||||
@@ -193,8 +176,8 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<!-- Settings Row 2: Timer Click, Ritardo, Multi-Click -->
|
<!-- Settings Row 2: Timer Click, Ritardo -->
|
||||||
<Grid Grid.Row="6" Margin="12,6,12,0">
|
<Grid Grid.Row="5" Margin="12,6,12,0">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="8" />
|
<ColumnDefinition Width="8" />
|
||||||
@@ -215,12 +198,12 @@
|
|||||||
<!-- Ritardo -->
|
<!-- Ritardo -->
|
||||||
<StackPanel Grid.Row="0" Grid.Column="2" Orientation="Vertical">
|
<StackPanel Grid.Row="0" Grid.Column="2" Orientation="Vertical">
|
||||||
<TextBlock Text="Ritardo (ms)" FontSize="11" />
|
<TextBlock Text="Ritardo (ms)" FontSize="11" />
|
||||||
<TextBox x:Name="ClickDelayBox" Style="{StaticResource NumericBoxStyle}" Text="100" Width="Auto" ToolTip="Ritardo aggiuntivo in millisecondi" TextChanged="ClickDelayBox_TextChanged" />
|
<TextBox x:Name="ClickDelayBox" Style="{StaticResource NumericBoxStyle}" Text="0" Width="Auto" ToolTip="Ritardo aggiuntivo in millisecondi (0 = massima velocità)" TextChanged="ClickDelayBox_TextChanged" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<!-- Bidders section header with clear button -->
|
<!-- Bidders section header with clear button -->
|
||||||
<Grid Grid.Row="8" Margin="12,8,12,4">
|
<Grid Grid.Row="6" Margin="12,8,12,4">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
@@ -239,7 +222,7 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<DataGrid x:Name="BiddersGrid" Grid.Row="9" Margin="12,0,12,0" AutoGenerateColumns="False" HeadersVisibility="Column" CanUserAddRows="False" IsReadOnly="True" Height="90" Background="#091018" RowBackground="#0B1220" AlternatingRowBackground="#081016" Foreground="#E6EDF3" GridLinesVisibility="None">
|
<DataGrid x:Name="BiddersGrid" Grid.Row="7" Margin="12,0,12,0" AutoGenerateColumns="False" HeadersVisibility="Column" CanUserAddRows="False" IsReadOnly="True" Height="90" Background="#091018" RowBackground="#0B1220" AlternatingRowBackground="#081016" Foreground="#E6EDF3" GridLinesVisibility="None">
|
||||||
<DataGrid.Resources>
|
<DataGrid.Resources>
|
||||||
<Style TargetType="DataGridColumnHeader">
|
<Style TargetType="DataGridColumnHeader">
|
||||||
<Setter Property="Background" Value="#0F1720" />
|
<Setter Property="Background" Value="#0F1720" />
|
||||||
@@ -258,7 +241,7 @@
|
|||||||
</DataGrid.Columns>
|
</DataGrid.Columns>
|
||||||
</DataGrid>
|
</DataGrid>
|
||||||
|
|
||||||
<Grid Grid.Row="10" Margin="12,6,12,4">
|
<Grid Grid.Row="8" Margin="12,6,12,4">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
@@ -277,7 +260,7 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<TextBox x:Name="LogBox" Grid.Row="11" Margin="12,0,12,12" IsReadOnly="True" VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" AcceptsReturn="True" Style="{StaticResource LogBoxStyle}" />
|
<TextBox x:Name="LogBox" Grid.Row="9" Margin="12,0,12,12" IsReadOnly="True" VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" AcceptsReturn="True" Style="{StaticResource LogBoxStyle}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
@@ -291,20 +274,50 @@
|
|||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<!-- Address bar -->
|
<!-- Address bar con pulsanti navigazione -->
|
||||||
<Grid Grid.Row="0" Margin="12,12,12,6">
|
<Grid Grid.Row="0" Margin="12,12,12,6">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<TextBox x:Name="AddressBar" Grid.Column="0" Style="{StaticResource AddressBarStyle}"
|
<!-- Pulsante Indietro -->
|
||||||
|
<Button x:Name="BackButton" Grid.Column="0" Content="Indietro" Click="BackButton_Click"
|
||||||
|
Background="#374151" Foreground="White" Padding="12,8" Margin="0,0,6,0"
|
||||||
|
BorderThickness="0" FontWeight="SemiBold" FontSize="13" MinWidth="70" Height="38" IsEnabled="False">
|
||||||
|
<Button.Template>
|
||||||
|
<ControlTemplate TargetType="Button">
|
||||||
|
<Border Background="{TemplateBinding Background}" CornerRadius="6" SnapsToDevicePixels="True">
|
||||||
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Button.Template>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<!-- Pulsante Aggiorna -->
|
||||||
|
<Button x:Name="RefreshButton" Grid.Column="1" Content="Aggiorna" Click="RefreshButton_Click"
|
||||||
|
Background="#0EA5E9" Foreground="White" Padding="12,8" Margin="0,0,8,0"
|
||||||
|
BorderThickness="0" FontWeight="SemiBold" FontSize="13" MinWidth="80" Height="38">
|
||||||
|
<Button.Template>
|
||||||
|
<ControlTemplate TargetType="Button">
|
||||||
|
<Border Background="{TemplateBinding Background}" CornerRadius="6" SnapsToDevicePixels="True">
|
||||||
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Button.Template>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<!-- Barra indirizzo -->
|
||||||
|
<TextBox x:Name="AddressBar" Grid.Column="2" Style="{StaticResource AddressBarStyle}"
|
||||||
Text="https://it.bidoo.com" KeyDown="AddressBar_KeyDown"
|
Text="https://it.bidoo.com" KeyDown="AddressBar_KeyDown"
|
||||||
ToolTip="Inserisci URL di Bidoo (es: https://it.bidoo.com/asta/...)" />
|
ToolTip="Inserisci URL di Bidoo (es: https://it.bidoo.com/asta/...)" />
|
||||||
|
|
||||||
<Button x:Name="NavigateButton" Grid.Column="1" Content="Vai" Click="NavigateButton_Click"
|
<!-- Pulsante Vai -->
|
||||||
Background="#16A34A" Foreground="White" Padding="38,10" Margin="8,0,0,0"
|
<Button x:Name="NavigateButton" Grid.Column="3" Content="Vai" Click="NavigateButton_Click"
|
||||||
BorderThickness="0" FontWeight="Bold" FontSize="14" MinWidth="90">
|
Background="#16A34A" Foreground="White" Padding="28,10" Margin="8,0,0,0"
|
||||||
|
BorderThickness="0" FontWeight="Bold" FontSize="14" MinWidth="80" Height="38">
|
||||||
<Button.Template>
|
<Button.Template>
|
||||||
<ControlTemplate TargetType="Button">
|
<ControlTemplate TargetType="Button">
|
||||||
<Border Background="{TemplateBinding Background}" CornerRadius="6" SnapsToDevicePixels="True">
|
<Border Background="{TemplateBinding Background}" CornerRadius="6" SnapsToDevicePixels="True">
|
||||||
|
|||||||
@@ -69,7 +69,6 @@ namespace AutoBidder
|
|||||||
StartButton.Opacity = 1.0;
|
StartButton.Opacity = 1.0;
|
||||||
StopButton.IsEnabled = false;
|
StopButton.IsEnabled = false;
|
||||||
StopButton.Opacity = 0.5;
|
StopButton.Opacity = 0.5;
|
||||||
BackButton.IsEnabled = false;
|
|
||||||
|
|
||||||
webView.NavigationCompleted += WebView_NavigationCompleted;
|
webView.NavigationCompleted += WebView_NavigationCompleted;
|
||||||
webView.NavigationStarting += WebView_NavigationStarting;
|
webView.NavigationStarting += WebView_NavigationStarting;
|
||||||
@@ -170,9 +169,13 @@ namespace AutoBidder
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
BackButton.IsEnabled = webView.CoreWebView2 != null && webView.CoreWebView2.CanGoBack;
|
// ⚡ OTTIMIZZAZIONE: Update UI asincrono
|
||||||
|
Dispatcher.BeginInvoke(() =>
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
BackButton.IsEnabled = webView.CoreWebView2 != null && webView.CoreWebView2.CanGoBack;
|
||||||
|
|
||||||
var url = webView.CoreWebView2?.Source ?? webView.Source?.ToString();
|
var url = webView.CoreWebView2?.Source ?? webView.Source?.ToString();
|
||||||
if (!string.IsNullOrEmpty(url))
|
if (!string.IsNullOrEmpty(url))
|
||||||
{
|
{
|
||||||
@@ -181,6 +184,7 @@ namespace AutoBidder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
@@ -290,15 +294,6 @@ namespace AutoBidder
|
|||||||
private void ClickTimerBox_TextChanged(object sender, TextChangedEventArgs e) => Log("Impostazione Click Timer cambiata: " + ClickTimerBox.Text);
|
private void ClickTimerBox_TextChanged(object sender, TextChangedEventArgs e) => Log("Impostazione Click Timer cambiata: " + ClickTimerBox.Text);
|
||||||
private void ClickDelayBox_TextChanged(object sender, TextChangedEventArgs e) => Log("Impostazione Click Delay cambiata: " + ClickDelayBox.Text);
|
private void ClickDelayBox_TextChanged(object sender, TextChangedEventArgs e) => Log("Impostazione Click Delay cambiata: " + ClickDelayBox.Text);
|
||||||
|
|
||||||
private void ClearStatsButton_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
ClickCountText.Text = "0";
|
|
||||||
ResetCountText.Text = "0";
|
|
||||||
Log("Statistiche resettate dall'utente");
|
|
||||||
_bidders.Clear();
|
|
||||||
UpdateBiddersGrid();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClearBiddersButton_Click(object sender, RoutedEventArgs e)
|
private void ClearBiddersButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -333,11 +328,21 @@ namespace AutoBidder
|
|||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DateTime _lastBiddersUpdate = DateTime.MinValue;
|
||||||
|
|
||||||
private void UpdateBiddersGrid()
|
private void UpdateBiddersGrid()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Dispatcher.Invoke(() =>
|
// ⚡ OTTIMIZZAZIONE: Aggiorna solo ogni 2 secondi per evitare lag
|
||||||
|
var now = DateTime.UtcNow;
|
||||||
|
if ((now - _lastBiddersUpdate).TotalMilliseconds < 2000)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_lastBiddersUpdate = now;
|
||||||
|
|
||||||
|
// ⚡ USA BeginInvoke ASINCRONO invece di Invoke per non bloccare
|
||||||
|
Dispatcher.BeginInvoke(() =>
|
||||||
{
|
{
|
||||||
var grid = FindName("BiddersGrid") as DataGrid;
|
var grid = FindName("BiddersGrid") as DataGrid;
|
||||||
if (grid != null)
|
if (grid != null)
|
||||||
@@ -350,11 +355,20 @@ namespace AutoBidder
|
|||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string _lastPriceText = "";
|
||||||
|
|
||||||
private void SetCurrentPriceText(string text)
|
private void SetCurrentPriceText(string text)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Dispatcher.Invoke(() =>
|
// ⚡ OTTIMIZZAZIONE: Non aggiornare se il prezzo non è cambiato
|
||||||
|
if (_lastPriceText == text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_lastPriceText = text;
|
||||||
|
|
||||||
|
// ⚡ USA BeginInvoke ASINCRONO
|
||||||
|
Dispatcher.BeginInvoke(() =>
|
||||||
{
|
{
|
||||||
var tb = FindName("CurrentPriceText") as TextBlock;
|
var tb = FindName("CurrentPriceText") as TextBlock;
|
||||||
if (tb != null) tb.Text = text;
|
if (tb != null) tb.Text = text;
|
||||||
@@ -368,20 +382,22 @@ namespace AutoBidder
|
|||||||
var entry = $"{DateTime.Now:HH:mm:ss} - {message}{Environment.NewLine}";
|
var entry = $"{DateTime.Now:HH:mm:ss} - {message}{Environment.NewLine}";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Dispatcher.Invoke(() =>
|
// ⚡ OTTIMIZZAZIONE CRITICA: USA BeginInvoke per non bloccare MAI il thread di automazione
|
||||||
|
Dispatcher.BeginInvoke(() =>
|
||||||
{
|
{
|
||||||
if (LogBox != null)
|
if (LogBox != null)
|
||||||
{
|
{
|
||||||
// Gestione performance: limita numero righe log
|
// ⚡ Semplifica: AppendText direttamente senza split pesante ogni volta
|
||||||
var lines = LogBox.Text.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
|
LogBox.AppendText(entry);
|
||||||
if (lines.Length > MAX_LOG_LINES)
|
|
||||||
|
// ⚡ Controlla dimensione log solo ogni 100 righe circa
|
||||||
|
if (LogBox.LineCount > MAX_LOG_LINES + 100)
|
||||||
{
|
{
|
||||||
// Mantieni solo le ultime MAX_LOG_LINES righe
|
var lines = LogBox.Text.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
|
||||||
var recentLines = lines.Skip(lines.Length - MAX_LOG_LINES + 50).ToArray();
|
var recentLines = lines.Skip(lines.Length - MAX_LOG_LINES).ToArray();
|
||||||
LogBox.Text = string.Join(Environment.NewLine, recentLines);
|
LogBox.Text = string.Join(Environment.NewLine, recentLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogBox.AppendText(entry);
|
|
||||||
LogBox.ScrollToEnd();
|
LogBox.ScrollToEnd();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -647,18 +663,22 @@ namespace AutoBidder
|
|||||||
try { result = JsonSerializer.Deserialize<string>(result) ?? result; } catch { }
|
try { result = JsonSerializer.Deserialize<string>(result) ?? result; } catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read limits
|
// ⚡ OTTIMIZZAZIONE CRITICA: Lettura impostazioni veloce
|
||||||
int maxClicks = int.MaxValue, maxResets = int.MaxValue;
|
int maxClicks = int.MaxValue, maxResets = int.MaxValue;
|
||||||
double minPrice = 0.0, maxPrice = double.MaxValue;
|
double minPrice = 0.0, maxPrice = double.MaxValue;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Dispatcher.InvokeAsync(() =>
|
var settingsOp = Dispatcher.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
if (int.TryParse(MaxClicksBox.Text, out var mc) && mc > 0) maxClicks = mc;
|
if (int.TryParse(MaxClicksBox.Text, out var mc) && mc > 0) maxClicks = mc;
|
||||||
if (int.TryParse(MaxResetsBox.Text, out var mr) && mr > 0) maxResets = mr;
|
if (int.TryParse(MaxResetsBox.Text, out var mr) && mr > 0) maxResets = mr;
|
||||||
if (double.TryParse(MinPriceBox.Text.Replace(',', '.'), NumberStyles.Any, CultureInfo.InvariantCulture, out var mp)) minPrice = mp;
|
if (double.TryParse(MinPriceBox.Text.Replace(',', '.'), NumberStyles.Any, CultureInfo.InvariantCulture, out var mp)) minPrice = mp;
|
||||||
if (double.TryParse(MaxPriceBox.Text.Replace(',', '.'), NumberStyles.Any, CultureInfo.InvariantCulture, out var mpx) && mpx > 0) maxPrice = mpx;
|
if (double.TryParse(MaxPriceBox.Text.Replace(',', '.'), NumberStyles.Any, CultureInfo.InvariantCulture, out var mpx) && mpx > 0) maxPrice = mpx;
|
||||||
});
|
});
|
||||||
|
// ⚡ Usa valori default se timeout
|
||||||
|
var opStatus = settingsOp.Wait(TimeSpan.FromMilliseconds(10));
|
||||||
|
if (opStatus == System.Windows.Threading.DispatcherOperationStatus.Completed)
|
||||||
|
await settingsOp.Task;
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
@@ -675,9 +695,11 @@ namespace AutoBidder
|
|||||||
// ⭐ LOG quando cambia il bidder E REGISTRA IMMEDIATAMENTE
|
// ⭐ LOG quando cambia il bidder E REGISTRA IMMEDIATAMENTE
|
||||||
if (!string.IsNullOrWhiteSpace(currentBidder) && currentBidder != lastKnownBidder)
|
if (!string.IsNullOrWhiteSpace(currentBidder) && currentBidder != lastKnownBidder)
|
||||||
{
|
{
|
||||||
Log($"👤 Puntata di: {currentBidder}");
|
// ⚡ OTTIMIZZAZIONE: Log e registrazione separati per non bloccare
|
||||||
|
var bidderToLog = currentBidder;
|
||||||
|
Task.Run(() => Log($"👤 Puntata di: {bidderToLog}"));
|
||||||
|
|
||||||
// ⭐ REGISTRA SUBITO LA PUNTATA NELLA LISTA
|
// ⭐ REGISTRA SUBITO LA PUNTATA NELLA LISTA (senza bloccare)
|
||||||
RegisterBidder(currentBidder);
|
RegisterBidder(currentBidder);
|
||||||
|
|
||||||
lastKnownBidder = currentBidder;
|
lastKnownBidder = currentBidder;
|
||||||
@@ -772,11 +794,13 @@ namespace AutoBidder
|
|||||||
if (currentTimer > prevTimer + 0.5 && prevTimer < 30)
|
if (currentTimer > prevTimer + 0.5 && prevTimer < 30)
|
||||||
{
|
{
|
||||||
resetCount++;
|
resetCount++;
|
||||||
await Dispatcher.InvokeAsync(() => ResetCountText.Text = resetCount.ToString());
|
// ⚡ OTTIMIZZAZIONE: UI update asincrono
|
||||||
|
Dispatcher.BeginInvoke(() => ResetCountText.Text = resetCount.ToString());
|
||||||
|
|
||||||
// ⭐ Usa currentBidder invece di fare una nuova query
|
// ⭐ Usa currentBidder invece di fare una nuova query
|
||||||
var winnerName = !string.IsNullOrWhiteSpace(currentBidder) ? currentBidder : "Sconosciuto";
|
var winnerName = !string.IsNullOrWhiteSpace(currentBidder) ? currentBidder : "Sconosciuto";
|
||||||
Log($"🔄 Reset #{resetCount} - Winner: {winnerName}");
|
var cnt = resetCount;
|
||||||
|
Task.Run(() => Log($"🔄 Reset #{cnt} - Winner: {winnerName}"));
|
||||||
|
|
||||||
if (resetCount >= maxResets)
|
if (resetCount >= maxResets)
|
||||||
{
|
{
|
||||||
@@ -797,12 +821,17 @@ namespace AutoBidder
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Dispatcher.InvokeAsync(() =>
|
// ⚡ OTTIMIZZAZIONE: Lettura veloce con timeout minimo
|
||||||
|
var clickSettingsOp = Dispatcher.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
if (int.TryParse(ClickTimerBox.Text, out var ctv) && ctv >= 0 && ctv <= 8) clickTimerValue = ctv;
|
if (int.TryParse(ClickTimerBox.Text, out var ctv) && ctv >= 0 && ctv <= 8) clickTimerValue = ctv;
|
||||||
if (int.TryParse(ClickDelayBox.Text, out var cdm) && cdm >= 0 && cdm <= 2000) clickDelayMs = cdm;
|
if (int.TryParse(ClickDelayBox.Text, out var cdm) && cdm >= 0 && cdm <= 2000) clickDelayMs = cdm;
|
||||||
multiClickEnabled = MultiClickCheckBox.IsChecked == true;
|
multiClickEnabled = MultiClickCheckBox.IsChecked == true;
|
||||||
});
|
});
|
||||||
|
// ⚡ Timeout velocissimo: se non risponde in 5ms usa default
|
||||||
|
var opStatus = clickSettingsOp.Wait(TimeSpan.FromMilliseconds(5));
|
||||||
|
if (opStatus == System.Windows.Threading.DispatcherOperationStatus.Completed)
|
||||||
|
await clickSettingsOp.Task;
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
@@ -825,18 +854,27 @@ namespace AutoBidder
|
|||||||
if (clickSuccess)
|
if (clickSuccess)
|
||||||
{
|
{
|
||||||
clickCount++;
|
clickCount++;
|
||||||
await Dispatcher.InvokeAsync(() => ClickCountText.Text = clickCount.ToString());
|
// ⚡ OTTIMIZZAZIONE: Update UI asincrono non bloccante
|
||||||
|
Dispatcher.BeginInvoke(() => ClickCountText.Text = clickCount.ToString());
|
||||||
|
|
||||||
// ⭐ Usa il nome utente corrente (mai AutoBidder se abbiamo il nome)
|
// ⭐ Usa il nome utente corrente (mai AutoBidder se abbiamo il nome)
|
||||||
if (!string.IsNullOrWhiteSpace(_currentUserName))
|
if (!string.IsNullOrWhiteSpace(_currentUserName))
|
||||||
{
|
{
|
||||||
RegisterBidder(_currentUserName);
|
RegisterBidder(_currentUserName);
|
||||||
Log($"✅ Click #{clickCount} ({_currentUserName}) - Timer: {timerValue}s (Delay: {clickDelayMs}ms)");
|
// ⚡ Log asincrono
|
||||||
|
var userName = _currentUserName;
|
||||||
|
var cnt = clickCount;
|
||||||
|
var timer = timerValue;
|
||||||
|
var delay = clickDelayMs;
|
||||||
|
Task.Run(() => Log($"✅ Click #{cnt} ({userName}) - Timer: {timer}s (Delay: {delay}ms)"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// ⭐ NON registrare AutoBidder nella lista, solo nel log
|
// ⭐ NON registrare AutoBidder nella lista, solo nel log
|
||||||
Log($"✅ Click #{clickCount} (AutoBidder) - Timer: {timerValue}s (Delay: {clickDelayMs}ms)");
|
var cnt = clickCount;
|
||||||
|
var timer = timerValue;
|
||||||
|
var delay = clickDelayMs;
|
||||||
|
Task.Run(() => Log($"✅ Click #{cnt} (AutoBidder) - Timer: {timer}s (Delay: {delay}ms)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clickCount >= maxClicks)
|
if (clickCount >= maxClicks)
|
||||||
@@ -849,7 +887,8 @@ namespace AutoBidder
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log($"⚠️ Click fallito - Timer: {timerValue}s");
|
var timer = timerValue;
|
||||||
|
Task.Run(() => Log($"⚠️ Click fallito - Timer: {timer}s"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((DateTime.UtcNow - lastDecisionLog) > TimeSpan.FromSeconds(3))
|
else if ((DateTime.UtcNow - lastDecisionLog) > TimeSpan.FromSeconds(3))
|
||||||
@@ -863,34 +902,41 @@ namespace AutoBidder
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ⚡ POLLING DINAMICO ULTRA-AGGRESSIVO per evitare micro-lag
|
||||||
int pollDelay;
|
int pollDelay;
|
||||||
if (double.TryParse(timerValue, NumberStyles.Any, CultureInfo.InvariantCulture, out var timerDouble))
|
if (double.TryParse(timerValue, NumberStyles.Any, CultureInfo.InvariantCulture, out var timerDouble))
|
||||||
{
|
{
|
||||||
if (timerDouble < 2.0)
|
if (timerDouble < 1.5)
|
||||||
{
|
{
|
||||||
pollDelay = 30;
|
// ⚡ ULTRA-CRITICO: polling ogni 20ms
|
||||||
|
pollDelay = 20;
|
||||||
}
|
}
|
||||||
else if (timerDouble < 3.0)
|
else if (timerDouble < 2.5)
|
||||||
|
{
|
||||||
|
// ⚡ CRITICO: polling ogni 40ms
|
||||||
|
pollDelay = 40;
|
||||||
|
}
|
||||||
|
else if (timerDouble < 3.5)
|
||||||
|
{
|
||||||
|
pollDelay = 80;
|
||||||
|
}
|
||||||
|
else if (timerDouble < 5.0)
|
||||||
|
{
|
||||||
|
pollDelay = 150;
|
||||||
|
}
|
||||||
|
else if (timerDouble < 8.0)
|
||||||
|
{
|
||||||
|
pollDelay = 250;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pollDelay = 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
pollDelay = 100;
|
pollDelay = 100;
|
||||||
}
|
}
|
||||||
else if (timerDouble < 4.0)
|
|
||||||
{
|
|
||||||
pollDelay = 150;
|
|
||||||
}
|
|
||||||
else if (timerDouble < 6.0)
|
|
||||||
{
|
|
||||||
pollDelay = 200;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pollDelay = 300;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pollDelay = 150;
|
|
||||||
}
|
|
||||||
|
|
||||||
await Task.Delay(pollDelay, token);
|
await Task.Delay(pollDelay, token);
|
||||||
}
|
}
|
||||||
@@ -943,11 +989,17 @@ namespace AutoBidder
|
|||||||
|
|
||||||
private async Task<bool> PerformOptimizedClick(int delayMs, bool multiClickEnabled, CancellationToken token)
|
private async Task<bool> PerformOptimizedClick(int delayMs, bool multiClickEnabled, CancellationToken token)
|
||||||
{
|
{
|
||||||
// Script click ultra-veloce e affidabile
|
// ⚡ Script click ULTRA-VELOCE con cache del bottone
|
||||||
const string optimizedClickScript = @"
|
const string optimizedClickScript = @"
|
||||||
(function(){
|
(function(){
|
||||||
try {
|
try {
|
||||||
var btn = document.querySelector('a.auction-btn-bid:not([disabled]), .auction-btn-bid:not([disabled])');
|
// ⚡ Cache del bottone per velocità
|
||||||
|
var btn = window._cachedBidBtn;
|
||||||
|
var now = Date.now();
|
||||||
|
|
||||||
|
// ⚡ Riusa cache se recente (< 500ms)
|
||||||
|
if (!btn || !document.contains(btn) || (window._cachedBidBtnTime && now - window._cachedBidBtnTime > 500)) {
|
||||||
|
btn = document.querySelector('a.auction-btn-bid:not([disabled]), .auction-btn-bid:not([disabled])');
|
||||||
|
|
||||||
if(!btn) {
|
if(!btn) {
|
||||||
var btns = document.querySelectorAll('a, button');
|
var btns = document.querySelectorAll('a, button');
|
||||||
@@ -958,23 +1010,17 @@ namespace AutoBidder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window._cachedBidBtn = btn;
|
||||||
|
window._cachedBidBtnTime = now;
|
||||||
|
}
|
||||||
|
|
||||||
if(!btn) return JSON.stringify({success: false});
|
if(!btn) return JSON.stringify({success: false});
|
||||||
|
|
||||||
// Click tripli rapidi per massima affidabilità
|
// ⚡ Click diretto SENZA focus (più veloce)
|
||||||
btn.focus();
|
|
||||||
btn.click();
|
|
||||||
btn.click();
|
|
||||||
btn.click();
|
btn.click();
|
||||||
|
|
||||||
// Mouse event per compatibilità
|
// ⚡ Secondo click immediato per affidabilità
|
||||||
var r = btn.getBoundingClientRect();
|
btn.click();
|
||||||
var evt = new MouseEvent('click', {
|
|
||||||
bubbles: true,
|
|
||||||
cancelable: true,
|
|
||||||
clientX: r.left + r.width/2,
|
|
||||||
clientY: r.top + r.height/2
|
|
||||||
});
|
|
||||||
btn.dispatchEvent(evt);
|
|
||||||
|
|
||||||
return JSON.stringify({success: true});
|
return JSON.stringify({success: true});
|
||||||
|
|
||||||
@@ -985,19 +1031,19 @@ namespace AutoBidder
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Applica delay se configurato
|
// ⚡ OTTIMIZZAZIONE: Delay solo se > 50ms (sotto è irrilevante)
|
||||||
if (delayMs > 0)
|
if (delayMs > 50)
|
||||||
{
|
{
|
||||||
await Task.Delay(delayMs, token);
|
await Task.Delay(delayMs, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Esegui click
|
// ⚡ Esegui click con timeout ULTRA-CORTO (500ms invece di 2s)
|
||||||
string? clickResult = null;
|
string? clickResult = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var clickOp = Dispatcher.InvokeAsync(() => webView.ExecuteScriptAsync(optimizedClickScript));
|
var clickOp = Dispatcher.InvokeAsync(() => webView.ExecuteScriptAsync(optimizedClickScript));
|
||||||
var clickTask = await clickOp.Task.ConfigureAwait(false);
|
var clickTask = await clickOp.Task.ConfigureAwait(false);
|
||||||
clickResult = await clickTask.WaitAsync(TimeSpan.FromSeconds(2), token).ConfigureAwait(false);
|
clickResult = await clickTask.WaitAsync(TimeSpan.FromMilliseconds(500), token).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (TimeoutException)
|
catch (TimeoutException)
|
||||||
{
|
{
|
||||||
@@ -1011,15 +1057,16 @@ namespace AutoBidder
|
|||||||
if (string.IsNullOrEmpty(clickResult))
|
if (string.IsNullOrEmpty(clickResult))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(clickResult) && clickResult.Length >= 2 && clickResult[0] == '"' && clickResult[^1] == '"' )
|
// ⚡ Parsing veloce
|
||||||
|
if (clickResult.Length >= 2 && clickResult[0] == '"' && clickResult[^1] == '"')
|
||||||
{
|
{
|
||||||
try { clickResult = JsonSerializer.Deserialize<string>(clickResult); } catch { }
|
try { clickResult = JsonSerializer.Deserialize<string>(clickResult); } catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonDocument? clickDoc = null;
|
// ⚡ Verifica successo rapida
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
clickDoc = JsonDocument.Parse(clickResult);
|
using var clickDoc = JsonDocument.Parse(clickResult);
|
||||||
var success = clickDoc.RootElement.GetProperty("success").GetBoolean();
|
var success = clickDoc.RootElement.GetProperty("success").GetBoolean();
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
@@ -1029,29 +1076,21 @@ namespace AutoBidder
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
clickDoc?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Multi-click se abilitato
|
// ⚡ Multi-click PARALLELO (non sequenziale) per velocità
|
||||||
if (multiClickEnabled)
|
if (multiClickEnabled)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 2; i++)
|
_ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await Task.Delay(30, token); // Delay ridotto per multi-click
|
await Task.Delay(20, token);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var multiOp = Dispatcher.InvokeAsync(() => webView.ExecuteScriptAsync(optimizedClickScript));
|
var multiOp = Dispatcher.InvokeAsync(() => webView.ExecuteScriptAsync(optimizedClickScript));
|
||||||
var multiTask = await multiOp.Task.ConfigureAwait(false);
|
var multiTask = await multiOp.Task.ConfigureAwait(false);
|
||||||
await multiTask.WaitAsync(TimeSpan.FromSeconds(1), token).ConfigureAwait(false);
|
await multiTask.WaitAsync(TimeSpan.FromMilliseconds(300), token).ConfigureAwait(false);
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
catch { }
|
||||||
|
}, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user