diff --git a/Mimante/Assets/app.ico b/Mimante/Assets/app.ico
new file mode 100644
index 0000000..48f1da0
--- /dev/null
+++ b/Mimante/Assets/app.ico
@@ -0,0 +1,2 @@
+
+[Binary ICO placeholder removed in this environment]
diff --git a/Mimante/AutoBidder.csproj b/Mimante/AutoBidder.csproj
index 76218ca..25005d1 100644
--- a/Mimante/AutoBidder.csproj
+++ b/Mimante/AutoBidder.csproj
@@ -15,4 +15,9 @@
+
+
+
+
+
diff --git a/Mimante/Converters/Converters.xaml b/Mimante/Converters/Converters.xaml
index b0a3b67..bbd67de 100644
--- a/Mimante/Converters/Converters.xaml
+++ b/Mimante/Converters/Converters.xaml
@@ -6,4 +6,5 @@
+
diff --git a/Mimante/Converters/StartButtonOpacityConverter.cs b/Mimante/Converters/StartButtonOpacityConverter.cs
new file mode 100644
index 0000000..ee68135
--- /dev/null
+++ b/Mimante/Converters/StartButtonOpacityConverter.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace AutoBidder.Converters
+{
+ public class StartButtonOpacityConverter : IMultiValueConverter
+ {
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (values.Length == 2 && values[0] is bool isActive && values[1] is bool isPaused)
+ {
+ // Bright (1.0) when not active (can start) or when paused (can resume)
+ return (!isActive || isPaused) ? 1.0 : 0.5;
+ }
+ return 1.0;
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Mimante/MainWindow.xaml b/Mimante/MainWindow.xaml
index 38f0853..7179bad 100644
--- a/Mimante/MainWindow.xaml
+++ b/Mimante/MainWindow.xaml
@@ -1,424 +1,446 @@
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="clr-namespace:AutoBidder.Converters"
+ Title="AutoBidder v3.0" Height="800" Width="1400"
+ Background="#0a0a0a" Foreground="#FFFFFF"
+ WindowStartupLocation="CenterScreen">
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
+
+
-
-
+
+
-
-
+
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
-
-
+
+
-
-
-
-
-
-
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Mimante/MainWindow.xaml.cs b/Mimante/MainWindow.xaml.cs
index a45f694..7b72d74 100644
--- a/Mimante/MainWindow.xaml.cs
+++ b/Mimante/MainWindow.xaml.cs
@@ -49,7 +49,7 @@ namespace AutoBidder
// Carica aste salvate
LoadSavedAuctions();
- // Ensure initial global button states (pause/stop disabled until started)
+ // Ensure initial global button states (pause/stop disabled until starting)
UpdateGlobalControlButtons();
Log("[OK] AutoBidder v4.0 avviato (API-based)");
@@ -69,8 +69,11 @@ namespace AutoBidder
UpdateAuctionLog(_selectedAuction);
RefreshBiddersGrid(_selectedAuction);
}
- });
- }
+
+ // Aggiorna lo stato dei bottoni globali quando cambia stato di un'asta
+ UpdateGlobalControlButtons();
+ });
+ }
private void AuctionMonitor_OnBidExecuted(AuctionInfo auction, BidResult result)
{
@@ -172,20 +175,38 @@ namespace AutoBidder
private void StartButton_Click(object sender, RoutedEventArgs e)
{
- if (_isAutomationActive) return;
-
try
{
- // Ensure all auctions are active and not paused
- SetAllActive(true);
+ if (!_isAutomationActive)
+ {
+ // Start the monitor and ensure existing auctions are active
+ foreach (var vm in _auctionViewModels)
+ {
+ vm.IsActive = true;
+ vm.IsPaused = false;
+ }
- // Avvia monitoraggio
- _auctionMonitor.Start();
- _isAutomationActive = true;
+ _auctionMonitor.Start();
+ _isAutomationActive = true;
+ Log("Monitoraggio avviato!");
+ }
+ else
+ {
+ // Monitoring already running: resume/activate auctions (start those paused/stopped)
+ foreach (var vm in _auctionViewModels)
+ {
+ if (!vm.IsActive)
+ {
+ vm.IsActive = true;
+ }
+
+ // Always clear pause to resume bidding
+ vm.IsPaused = false;
+ }
+ Log("Avviate/riprese le aste (tutte)");
+ }
UpdateGlobalControlButtons();
-
- Log("Monitoraggio avviato!");
}
catch (Exception ex)
{
@@ -206,7 +227,10 @@ namespace AutoBidder
}
// Set all auctions to stopped
- SetAllActive(false);
+ foreach (var vm in _auctionViewModels)
+ {
+ vm.IsActive = false;
+ }
UpdateGlobalControlButtons();
@@ -372,6 +396,17 @@ namespace AutoBidder
}
}
+ private void SelectedMaxClicks_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ if (_selectedAuction != null && sender is TextBox tb)
+ {
+ if (int.TryParse(tb.Text, out var value) && value >= 0)
+ {
+ _selectedAuction.AuctionInfo.MaxClicks = value;
+ }
+ }
+ }
+
private void ResetSettingsButton_Click(object sender, RoutedEventArgs e)
{
if (_selectedAuction == null) return;
@@ -428,7 +463,7 @@ namespace AutoBidder
if (result == MessageBoxResult.Yes)
{
_selectedAuction.AuctionInfo.AuctionLog.Clear();
- SelectedAuctionLog.Text = "";
+ SelectedAuctionLog.Document.Blocks.Clear();
Log($"Log pulito: {_selectedAuction.Name}");
}
}
@@ -773,9 +808,23 @@ namespace AutoBidder
try
{
var auctionInfo = auction.AuctionInfo;
- var logText = string.Join(Environment.NewLine, auctionInfo.AuctionLog);
- SelectedAuctionLog.Text = logText;
+ SelectedAuctionLog.Document.Blocks.Clear();
+ foreach (var entry in auctionInfo.AuctionLog)
+ {
+ var upper = entry.ToUpperInvariant();
+ var color = System.Windows.Media.Brushes.LightSkyBlue; // default: parsing/info -> blue
+ if (upper.Contains("[ERRORE]") || upper.Contains("[FAIL]") || upper.Contains("EXCEPTION"))
+ color = System.Windows.Media.Brushes.IndianRed;
+ else if (upper.Contains("[WARN]") || upper.Contains("WARN"))
+ color = System.Windows.Media.Brushes.Orange;
+
+ var p = new System.Windows.Documents.Paragraph { Margin = new Thickness(0) };
+ var r = new System.Windows.Documents.Run(entry) { Foreground = color };
+ p.Inlines.Add(r);
+ SelectedAuctionLog.Document.Blocks.Add(p);
+ }
+
SelectedAuctionLog.ScrollToEnd();
}
catch { }
@@ -927,14 +976,45 @@ namespace AutoBidder
}
}
- private void Log(string message)
+ private enum LogLevel { Info, Warn, Error }
+
+ private void Log(string message, LogLevel level = LogLevel.Info)
{
+ // Reduced verbosity: only write concise messages
try
{
+ // Auto-detect severity if caller used default
+ if (level == LogLevel.Info)
+ {
+ var m = message.ToUpperInvariant();
+ if (m.Contains("[ERRORE]") || m.Contains("[FAIL]") || m.Contains("EXCEPTION") || m.Contains("ERROR"))
+ level = LogLevel.Error;
+ else if (m.Contains("[WARN]") || m.Contains("WARN") || m.Contains("[WARN"))
+ level = LogLevel.Warn;
+ else
+ level = LogLevel.Info;
+ }
+
Dispatcher.BeginInvoke(() =>
{
- var entry = $"{DateTime.Now:HH:mm:ss} - {message}{Environment.NewLine}";
- LogBox.AppendText(entry);
+ var para = new System.Windows.Documents.Paragraph();
+ para.Margin = new Thickness(0);
+ var run = new System.Windows.Documents.Run($"{DateTime.Now:HH:mm:ss} - {message}");
+ switch (level)
+ {
+ case LogLevel.Info:
+ run.Foreground = System.Windows.Media.Brushes.LightGray;
+ break;
+ case LogLevel.Warn:
+ run.Foreground = System.Windows.Media.Brushes.Orange;
+ break;
+ case LogLevel.Error:
+ run.Foreground = System.Windows.Media.Brushes.IndianRed;
+ run.FontWeight = FontWeights.Bold;
+ break;
+ }
+ para.Inlines.Add(run);
+ LogBox.Document.Blocks.Add(para);
LogBox.ScrollToEnd();
});
}
@@ -981,7 +1061,7 @@ namespace AutoBidder
vm.IsActive = true;
vm.IsPaused = false;
Log($"[START] Asta avviata: {vm.Name}");
- UpdateStartButtonState();
+ UpdateGlobalControlButtons();
}
}
@@ -991,7 +1071,7 @@ namespace AutoBidder
{
vm.IsPaused = true;
Log($"[PAUSA] Asta in pausa: {vm.Name}");
- UpdateStartButtonState();
+ UpdateGlobalControlButtons();
}
}
@@ -1001,7 +1081,7 @@ namespace AutoBidder
{
vm.IsActive = false;
Log($"[STOP] Asta fermata: {vm.Name}");
- UpdateStartButtonState();
+ UpdateGlobalControlButtons();
}
}
@@ -1041,69 +1121,51 @@ namespace AutoBidder
// When paused, Start and Stop should be enabled, Pause disabled
UpdateGlobalControlButtons();
}
-
- private void UpdateStartButtonState()
+
+ private void ClearGlobalLogButton_Click(object sender, RoutedEventArgs e)
{
- // Backwards compatibility: delegate to global control update
- UpdateGlobalControlButtons();
- }
-
- private void SetAllActive(bool active)
- {
- foreach (var vm in _auctionViewModels)
+ var result = MessageBox.Show("Pulire il log globale?", "Conferma", MessageBoxButton.YesNo, MessageBoxImage.Question);
+ if (result == MessageBoxResult.Yes)
{
- vm.IsActive = active;
- if (active)
- vm.IsPaused = false;
- }
- }
-
- private void SetAllPaused(bool paused)
- {
- foreach (var vm in _auctionViewModels)
- {
- if (vm.IsActive)
- vm.IsPaused = paused;
+ LogBox.Document.Blocks.Clear();
}
}
private void UpdateGlobalControlButtons()
{
- // Determine overall state
- bool anyActive = _auctionViewModels.Any(vm => vm.IsActive);
- bool anyPaused = _auctionViewModels.Any(vm => vm.IsActive && vm.IsPaused);
+ // Rules: darken (disable) global button only if ALL auctions are in that state
+ bool allActive = _auctionViewModels.All(vm => vm.IsActive && !vm.IsPaused);
+ bool allStopped = _auctionViewModels.All(vm => !vm.IsActive);
+ bool allPaused = _auctionViewModels.All(vm => vm.IsActive && vm.IsPaused);
- // Priority: if no active auctions => only Start enabled
- if (!anyActive)
+ // Start button: disabled/dark when allActive OR allPaused OR allStopped ?
+ // According to rule: darken if all in same state that matches the button meaning
+ if (allActive)
{
- StartButton.IsEnabled = true; StartButton.Opacity = 1.0;
- PauseAllButton.IsEnabled = false; PauseAllButton.Opacity = 0.5;
- StopButton.IsEnabled = false; StopButton.Opacity = 0.5;
- return;
- }
-
- // If any paused (regardless of monitoring state) -> Start & Stop enabled, Pause disabled
- if (anyPaused)
- {
- StartButton.IsEnabled = true; StartButton.Opacity = 1.0;
- PauseAllButton.IsEnabled = false; PauseAllButton.Opacity = 0.5;
- StopButton.IsEnabled = true; StopButton.Opacity = 1.0;
- return;
- }
-
- // Otherwise (some active, none paused)
- if (_isAutomationActive)
- {
- // Monitoring running: Start disabled, Pause and Stop enabled
StartButton.IsEnabled = false; StartButton.Opacity = 0.5;
- PauseAllButton.IsEnabled = true; PauseAllButton.Opacity = 1.0;
- StopButton.IsEnabled = true; StopButton.Opacity = 1.0;
}
else
{
- // Automation not running but auctions active and none paused: allow Start, Pause, Stop
StartButton.IsEnabled = true; StartButton.Opacity = 1.0;
+ }
+
+ // PauseAll button: darken if allPaused or allStopped
+ if (allPaused || allStopped)
+ {
+ PauseAllButton.IsEnabled = false; PauseAllButton.Opacity = 0.5;
+ }
+ else
+ {
PauseAllButton.IsEnabled = true; PauseAllButton.Opacity = 1.0;
+ }
+
+ // Stop button: darken if allStopped
+ if (allStopped)
+ {
+ StopButton.IsEnabled = false; StopButton.Opacity = 0.5;
+ }
+ else
+ {
StopButton.IsEnabled = true; StopButton.Opacity = 1.0;
}
}
diff --git a/Mimante/Models/AuctionInfo.cs b/Mimante/Models/AuctionInfo.cs
index 95de7a9..b9c37df 100644
--- a/Mimante/Models/AuctionInfo.cs
+++ b/Mimante/Models/AuctionInfo.cs
@@ -19,6 +19,8 @@ namespace AutoBidder.Models
public double MaxPrice { get; set; } = 0;
public int MinResets { get; set; } = 0; // Numero minimo reset prima di puntare
public int MaxResets { get; set; } = 0; // Numero massimo reset (0 = illimitati)
+ // Numero massimo di click/puntate che il bot puņ eseguire per questa asta (0 = illimitato)
+ public int MaxClicks { get; set; } = 0;
// Stato asta
public bool IsActive { get; set; } = true;
diff --git a/Mimante/Services/AuctionMonitor.cs b/Mimante/Services/AuctionMonitor.cs
index e7324fa..12b2c2a 100644
--- a/Mimante/Services/AuctionMonitor.cs
+++ b/Mimante/Services/AuctionMonitor.cs
@@ -150,10 +150,10 @@ namespace AutoBidder.Services
lock (_auctions)
{
// Filtra aste che devono ancora essere monitorate
- // Esclude: pausa manuale, chiuse definitivamente, vinte, perse
+ // Include aste attive anche se messe in pausa: vogliamo continuare a monitorarle
+ // ma non inviare puntate per quelle in pausa.
activeAuctions = _auctions.Where(a =>
a.IsActive &&
- !a.IsPaused &&
!IsAuctionTerminated(a)
).ToList();
}
@@ -168,13 +168,13 @@ namespace AutoBidder.Services
var pollTasks = activeAuctions.Select(a => PollAndProcessAuction(a, token));
await Task.WhenAll(pollTasks);
- // Ottimizzazione polling aste in pausa
+ // Ottimizzazione polling per aste in pausa
bool anyPaused = false;
DateTime now = DateTime.Now;
int pauseDelayMs = 1000; // default
foreach (var a in activeAuctions)
{
- if (a.BidHistory.LastOrDefault()?.Notes?.Contains("PAUSA") == true)
+ if (a.IsPaused)
{
anyPaused = true;
// Se tra le 00:00 e le 09:55 polling ogni 60s
@@ -306,8 +306,8 @@ namespace AutoBidder.Services
UpdateAuctionHistory(auction, state);
// Verifica se puntare (solo se asta Running, NON se in pausa)
- if (state.Status == AuctionStatus.Running && ShouldBid(auction, state))
- {
+ if (state.Status == AuctionStatus.Running && ShouldBid(auction, state) && !auction.IsPaused)
+ {
auction.AddLog($"[TRIGGER] CONDIZIONI OK - Timer {state.Timer:F2}s <= {auction.TimerClick}s");
auction.AddLog($"[BID] Invio puntata...");
OnLog?.Invoke($"[BID] [{auction.AuctionId}] PUNTATA a {state.Timer:F2}s!");
@@ -355,6 +355,14 @@ namespace AutoBidder.Services
Success = result.Success,
Notes = result.Success ? $"EUR{result.NewPrice:F2}" : result.Error
});
+
+ // Se abbiamo raggiunto il numero massimo di click per l'asta, metti in pausa le puntate (ma continua il monitor)
+ if (auction.MaxClicks > 0 && auction.MyClicks >= auction.MaxClicks)
+ {
+ auction.IsPaused = true;
+ auction.AddLog($"[PAUSA] Massimo click ({auction.MaxClicks}) raggiunto - Puntate disabilitate");
+ OnLog?.Invoke($"[PAUSA] [{auction.AuctionId}] MaxClicks raggiunti");
+ }
}
}
catch (Exception ex)
@@ -385,6 +393,10 @@ namespace AutoBidder.Services
return false;
}
+ // Max clicks per auction
+ if (auction.MaxClicks > 0 && auction.MyClicks >= auction.MaxClicks)
+ return false;
+
return true;
}