Compare commits

...

2 Commits

Author SHA1 Message Date
Alberto Balbo
59d7e0c41f Aggiornamento alla versione 3.0.0
- Aggiornato il titolo e l'introduzione per riflettere le funzionalità.
- Aggiunti badge per la versione (3.0) e .NET (8.0).
- Riorganizzato il sommario e rinominato in "Indice".
- Espansa la sezione "Caratteristiche principali" con nuovi dettagli.
- Riformattati i requisiti di sistema per maggiore chiarezza.
- Riscritta la guida "Installazione e avvio" con istruzioni dettagliate.
- Aggiunta la sezione "Configurazione della sessione (cookie)".
- Ampliata la gestione delle aste con dettagli su operazioni e griglia.
- Inserite strategie consigliate per diversi scenari d'uso.
- Arricchita la sezione tecnica con dettagli su polling e puntate HTTP.
- Aggiunta descrizione su persistenza e diagnostica (es. esportazione CSV).
- Espansa la sezione FAQ con nuovi scenari di risoluzione problemi.
- Introdotte note su sicurezza e responsabilità nell'uso dell'app.
- Semplificata la sezione "Supporto" rimuovendo riferimenti privati.
- Aggiunte note tecniche per sviluppatori sui file principali del progetto.
- Rimossa la sezione "Changelog sintetico" e integrati i dettagli altrove.
- Riformattata la sezione "Licenza" per maggiore chiarezza.
2025-10-30 13:02:13 +01:00
Alberto Balbo
daf9ea31fc Miglioramenti logica e gestione attacco finale
- Aggiunta proprietà `FinalAttackThresholdSec` (0.8s) in `AuctionInfo.cs`.
- Implementata strategia di "quick re-poll" in `AuctionMonitor.cs` per confermare stato critico prima dell'attacco finale.
- Migliorata gestione delle eccezioni in `BidooApiClient.cs` con log dettagliati e tentativi alternativi.
- Registrazione del numero di offerte rimanenti dopo successo in `BidooApiClient.cs`.
- Ottimizzati messaggi di log per maggiore chiarezza e trasparenza.
- Rimossa logica obsoleta e aggiunti ritardi minimi tra tentativi di polling rapido.
2025-10-29 17:12:46 +01:00
4 changed files with 217 additions and 118 deletions

View File

@@ -50,6 +50,11 @@ namespace AutoBidder.Models
[System.Text.Json.Serialization.JsonIgnore]
public bool IsAttackInProgress { get; set; } = false;
// Quando viene considerato il "final attack" (secondi)
// Se il timer dell'asta scende sotto questo valore, viene eseguita la puntata finale.
// Default 0.8s per anticipare leggermente rispetto al valore precedente di 0.5s.
public double FinalAttackThresholdSec { get; set; } = 0.8;
/// <summary>
/// Aggiunge una voce al log dell'asta
/// </summary>

View File

@@ -335,37 +335,82 @@ namespace AutoBidder.Services
var latencyThreshold = 0.5; // seconds
if (!auction.IsAttackInProgress && state.Timer <= latencyThreshold)
{
// Enter attack state for this auction to avoid concurrent triggers
// Quick re-poll strategy: perform a couple of fast re-polls to confirm that the timer
// is still in the critical window and that the lastBidder did not change.
auction.IsAttackInProgress = true;
AuctionState? lastConfirmedState = state;
try
{
// Log detailed info into auction log
auction.AddLog($"[ATTACK] Final attack: Timer {state.Timer:F3}s <= {latencyThreshold}s -> executing final bid...");
auction.AddLog($"[ATTACK] Candidate final attack: Timer {state.Timer:F3}s <= {latencyThreshold}s. Performing quick re-polls to confirm...");
// Place final minimal bid (one GET with auctionID & submit=1)
var finalResult = await _apiClient.PlaceBidFinalAsync(auction.AuctionId, auction.OriginalUrl);
int attempts = 2;
for (int i = 0; i < attempts; i++)
{
try
{
using var cts = CancellationTokenSource.CreateLinkedTokenSource(token);
// small timeout for quick verification
cts.CancelAfter(TimeSpan.FromMilliseconds(400));
var quickState = await _apiClient.PollAuctionStateAsync(auction.AuctionId, auction.OriginalUrl, cts.Token);
if (quickState != null)
{
auction.AddLog($"[ATTACK] Quick re-poll #{i + 1}: Timer {quickState.Timer:F3}s, Bidder: {quickState.LastBidder}");
// If bidder changed to someone else, abort
if (!string.Equals(quickState.LastBidder, state.LastBidder, StringComparison.OrdinalIgnoreCase))
{
auction.AddLog($"[ATTACK] Aborting final attack: last bidder changed from '{state.LastBidder}' to '{quickState.LastBidder}'");
return;
}
// If timer increased above threshold, abort
if (quickState.Timer > latencyThreshold)
{
auction.AddLog($"[ATTACK] Aborting final attack: quickState.Timer {quickState.Timer:F3}s > threshold {latencyThreshold}s");
return;
}
// Confirmed critical window
lastConfirmedState = quickState;
break; // proceed to place bid
}
else
{
auction.AddLog($"[ATTACK] Quick re-poll #{i + 1} returned no data (timeout/error).\n");
}
}
catch (Exception exQuick)
{
auction.AddLog($"[ATTACK] Quick re-poll #{i + 1} exception: {exQuick.GetType().Name} - {exQuick.Message}");
}
// tiny delay between attempts
await Task.Delay(30, token);
}
// If no quickState confirmed but initial state indicated critical window, proceed but warn
if (lastConfirmedState == null)
{
auction.AddLog("[ATTACK] No quick re-poll confirmed state. Proceeding with final bid based on initial observation (risk of false positive).");
}
// Place final bid using the same request format as manual bids to mimic manual behavior
auction.AddLog($"[ATTACK] Executing final bid (using manual-format payload) for {auction.AuctionId} (confirmed: { (lastConfirmedState != null) })...");
var finalResult = await _apiClient.PlaceBidAsync(auction.AuctionId, auction.OriginalUrl);
auction.LastClickAt = DateTime.UtcNow;
OnBidExecuted?.Invoke(auction, finalResult);
if (finalResult.Success)
{
// Success: log concise global, detailed per-auction
auction.AddLog($"[OK] Final bid OK: {finalResult.LatencyMs}ms -> EUR{finalResult.NewPrice:F2}");
OnLog?.Invoke($"[OK] Puntata riuscita su {auction.Name} ({auction.AuctionId}): {finalResult.LatencyMs}ms");
// After success, an expiration may be extended by server (T_exp = now + 8s)
// We simply resume normal monitoring to observe new timer
}
else
{
// Failure cases: log and do not attempt immediate retries
auction.AddLog($"[FAIL] Final bid failed: {finalResult.Error}");
OnLog?.Invoke($"[FAIL] Puntata fallita su {auction.Name} ({auction.AuctionId}): {finalResult.Error}");
}
// Always add history entry
auction.BidHistory.Add(new BidHistory
{
Timestamp = finalResult.Timestamp,
@@ -383,7 +428,6 @@ namespace AutoBidder.Services
auction.IsAttackInProgress = false;
}
// Done with final attack; skip the older branch below
return;
}

View File

@@ -234,8 +234,12 @@ namespace AutoBidder.Services
}
catch (Exception ex)
{
Log($"[ERRORE] [{auctionId}] API non ha risposto (motivo: eccezione)", null); // globale
Log($"API non ha risposto: {ex.GetType().Name} - {ex.Message}", auctionId); // asta
// Global concise message
Log($"[ERRORE] [{auctionId}] API non ha risposto (verificare dettagli nel log asta)", null);
// Detailed per-auction log with full exception and context
var details = ex.ToString();
details = "[API EXCEPTION] " + details;
Log(details, auctionId);
return null;
}
}
@@ -392,8 +396,18 @@ namespace AutoBidder.Services
{
result.NewPrice = priceIndex * 0.01;
}
// Parse remaining bids from response if present: ok|324|...
var parts2 = responseText.Split('|');
if (parts2.Length > 1 && int.TryParse(parts2[1], out var remaining))
{
_session.RemainingBids = remaining;
Log($"[BID SUCCESS] ✓ Bid placed successfully - Remaining bids: {remaining}", auctionId);
}
else
{
Log("[BID SUCCESS] ✓ Bid placed successfully", auctionId);
}
}
else if (responseText.StartsWith("error", StringComparison.OrdinalIgnoreCase) || responseText.StartsWith("no|", StringComparison.OrdinalIgnoreCase))
{
result.Success = false;
@@ -413,14 +427,38 @@ namespace AutoBidder.Services
result.Error = string.IsNullOrEmpty(responseText) ? $"HTTP {(int)response.StatusCode}" : responseText;
Log($"[BID ERROR] Unexpected response format: {result.Error}", auctionId);
}
// If initial attempt failed or returned unexpected format, try alternate payload once
if (!result.Success)
{
Log($"[BID] Initial attempt failed for {auctionId}. Trying alternate payload (auctionID=...)\n", auctionId);
try
{
var alt = await PlaceBidFinalAsync(auctionId, auctionUrl);
// Merge alt result into result (prefer alt)
return alt;
}
catch (Exception exAlt)
{
Log($"[BID] Alternate attempt threw: {exAlt.GetType().Name} - {exAlt.Message}", auctionId);
}
}
return result;
}
catch (Exception ex)
{
result.Success = false;
result.Error = ex.Message;
Log($"[BID EXCEPTION] {ex.GetType().Name}: {ex.Message}", auctionId);
Log($"[BID EXCEPTION] StackTrace available in debug logs", auctionId);
// Generic global-style hint (via auction log event, AuctionMonitor will emit concise global message)
Log($"[BID EXCEPTION] Errore durante il piazzamento della puntata: {ex.GetType().Name}. Vedere log asta per dettagli.", auctionId);
// Detailed per-auction info
var sb = new System.Text.StringBuilder();
sb.AppendLine("[BID EXCEPTION DETAILED]");
sb.AppendLine(ex.ToString());
sb.AppendLine($"RequestUri: { (auctionUrl ?? "https://it.bidoo.com/bid.php") }");
sb.AppendLine($"HttpClient.Timeout: {_httpClient.Timeout.TotalSeconds}s");
sb.AppendLine($"CookiePresent: {!string.IsNullOrEmpty(_session.CookieString)} (length: {(_session.CookieString?.Length ?? 0)})");
Log(sb.ToString(), auctionId);
return result;
}
}
@@ -492,7 +530,14 @@ namespace AutoBidder.Services
{
result.Success = false;
result.Error = ex.Message;
Log($"[BID EXCEPTION] {ex.GetType().Name}: {ex.Message}", auctionId);
Log($"[BID EXCEPTION] Errore durante il piazzamento della puntata (final): {ex.GetType().Name}. Vedere log asta per dettagli.", auctionId);
var sb = new System.Text.StringBuilder();
sb.AppendLine("[BID FINAL EXCEPTION DETAILED]");
sb.AppendLine(ex.ToString());
sb.AppendLine($"RequestUri: { (auctionUrl ?? "https://it.bidoo.com/bid.php") }");
sb.AppendLine($"HttpClient.Timeout: {_httpClient.Timeout.TotalSeconds}s");
sb.AppendLine($"CookiePresent: {!string.IsNullOrEmpty(_session.CookieString)} (length: {(_session.CookieString?.Length ?? 0)})");
Log(sb.ToString(), auctionId);
return result;
}
}

193
README.md
View File

@@ -1,143 +1,148 @@
# AutoBidder - Guida completa all'uso
> AutoBidder è uno strumento desktop per Windows (WPF, .NET 8) pensato per automatizzare le offerte sul sito Bidoo.com. Questa guida descrive caratteristiche, installazione, configurazione, modalità operative, strategie avanzate, dettagli tecnici e risoluzione dei problemi.
> AutoBidder è un'app desktop per Windows (WPF, .NET 8) progettata per monitorare aste su Bidoo e inviare offerte automatiche tramite richieste HTTP.
![Version](https://img.shields.io/badge/version-3.0-blue)
![.NET](https://img.shields.io/badge/.NET-8.0-purple)
---
Sommario
Indice
- Panoramica
- Caratteristiche principali
- Requisiti di sistema
- Installazione e avvio
- Guida rapida (primi passi)
- Gestione aste tramite griglia
- Strategie e consigli pratici
- Dettagli tecnici: Polling e Click HTTP
- Impostazioni e persistenza
- Esportazione e diagnostica
- FAQ e risoluzione problemi
- Changelog sintetico
- Installazione e build
- Avvio e guida rapida
- Configurazione della sessione (cookie)
- Gestione aste e griglia principale
- Impostazioni e strategie consigliate
- Dettagli tecnici
- Persistenza, esportazione e diagnostica
- FAQ e risoluzione dei problemi
- Supporto
---
## Caratteristiche principali
- Monitoraggio in tempo reale di tutte le aste tramite griglia unica
- Polling adattivo solo HTTP per ridurre uso di CPU e RAM
- Click HTTP diretto (reverse engineered) con cookie manuale
- Persistenza della lista aste (`auctions.json`) e esportazione CSV delle statistiche
- UI dark theme moderna con griglia in tempo reale, dettagli asta, log e contatori
Panoramica
AutoBidder monitora e gestisce più aste simultaneamente tramite polling HTTP verso gli endpoint di Bidoo. L'app è pensata per offrire precisione nelle puntate minimizzando l'uso di risorse (CPU/RAM).
Caratteristiche principali
- Monitoraggio in tempo reale delle aste tramite griglia unica
- Polling HTTP adattivo per aggiornare timer e prezzo delle aste
- Invio delle puntate con richieste HTTP dirette (GET a endpoint bid)
- Inserimento manuale del cookie di sessione tramite dialog dedicato
- Persistenza della lista aste in `auctions.json` e esportazione CSV delle statistiche
- Interfaccia scura, log per-asta e contatori in tempo reale
Requisiti di sistema
## Requisiti di sistema
- Windows 10 (1809+) o Windows 11
- .NET 8.0 Runtime
- RAM: 4 GB (consigliati 8 GB)
- Connessione internet stabile
- Connessione Internet stabile
## Installazione e avvio
1. Assicurarsi di avere .NET 8.0 Runtime installato: `dotnet --version` (output: 8.0.x)
Installazione e build
1. Verificare il Runtime .NET 8.0: `dotnet --version` (output: 8.0.x)
2. Clonare il repository (privato):
- `git clone https://192.168.30.23/Alby96/Mimante`
3. Costruire il progetto:
3. Dal folder del progetto eseguire:
- `dotnet restore`
- `dotnet build --configuration Release`
4. Eseguire l'app:
- `dotnet run` (dalla cartella del progetto) oppure avviare `AutoBidder.exe` in `bin\Release\net8.0-windows`
- `dotnet run` oppure avviare `AutoBidder.exe` in `bin\Release\net8.0-windows`
## Guida rapida (primi passi)
1. Avvia l'app: l'interfaccia principale mostra la griglia delle aste monitorate.
2. Configura la sessione: copia il cookie `__stattrb` dal browser (F12 > Application > Cookies) e inseriscilo tramite il dialog di configurazione.
3. Aggiungi aste: usa il pulsante `+ Aggiungi` per inserire URL o ID delle aste da monitorare.
4. Configura impostazioni per ogni asta (Timer Click, Min/Max Price, Max Clicks, Max Resets, Ritardo).
5. Premi `Avvia Tutti` per attivare il monitoraggio e le puntate automatiche.
Avvio e guida rapida
## Gestione aste tramite griglia
- Tutte le aste sono gestite tramite una griglia unica.
- Puoi avviare, mettere in pausa, fermare o puntare manualmente su ogni asta direttamente dalla griglia.
- Non esistono più modalità "Asta Singola" o "Multi-Asta": tutto è gestito in modo uniforme.
1. Avvia l'app: la finestra principale mostra la griglia delle aste monitorate.
2. Configura la sessione: apri il dialog `Configura Sessione` e incolla il cookie di sessione (vedi sezione sotto).
3. Aggiungi aste: clicca `+ Aggiungi` e inserisci l'URL o l'ID dell'asta.
4. Per ogni asta imposta `Timer Click`, `Min/Max Price`, `Max Clicks` e altre opzioni.
5. Premi `Avvia Tutti` per iniziare il monitoraggio e l'invio automatico delle puntate.
## Strategie consigliate
- Monitoraggio massivo: aggiungi molte aste tramite URL o ID, imposta Timer Click basso e limiti di prezzo.
- Asta ad alto valore: Timer Click 0-1, Ritardo 0ms.
- Caccia all'affare: Max Price basso, monitora molte aste con Timer Click 0.
Configurazione della sessione (cookie)
## Approfondimento tecnico
Per inviare puntate HTTP è necessario fornire il cookie di sessione della tua istanza di Bidoo. L'app espone un dialog (`Configura Sessione`) con un campo multilinea in cui incollare il valore dell'header `Cookie` o i cookie rilevanti (es. `PHPSESSID`, `user_token`).
### Polling adattivo
- Il monitoraggio avviene solo tramite chiamate HTTP dirette alle API di Bidoo.
- Nessun WebView2 viene utilizzato, nemmeno come fallback.
- Il polling si adatta al timer dell'asta per ottimizzare la frequenza delle richieste.
Come ottenere il cookie da Chrome:
- Apri Chrome, premi `F12` per aprire gli Strumenti per sviluppatori.
- Vai alla scheda `Application` ? `Storage` ? `Cookies` ? seleziona `bidoo.com`.
- Copia il valore del cookie di sessione oppure l'intero header cookie.
- Incollalo nel campo della finestra `Configura Sessione` e premi `OK`.
### Click HTTP diretto
- Al momento dell'azione, il client costruisce una GET verso l'endpoint reverse engineered di Bidoo tipo:
`GET https://it.bidoo.com/bid.php?AID=81204347&sup=0&shock=0`
- Richiede i cookie di sessione (`__stattrb`) che vengono copiati manualmente dal browser.
- Latenza tipica: 10-30ms.
- Non esiste più alcun fallback WebView2: tutte le puntate sono gestite solo via HTTP.
Note importanti sulla gestione cookie:
- I cookie inseriti vengono mantenuti solo in memoria durante l'esecuzione e **non** vengono salvati in chiaro su disco.
- Se il cookie scade è necessario copiarne uno nuovo tramite la stessa procedura.
### Sincronizzazione cookie
- I cookie vengono inseriti manualmente dall'utente tramite dialog.
- Non vengono mai salvati su disco in chiaro.
- Se il cookie scade, è necessario copiarlo nuovamente dal browser.
Gestione aste e griglia principale
## Persistenza e file locali
- Lista aste manuali salvata in:
`%AppData%\AutoBidder\auctions.json`
- La lista viene ricaricata automaticamente all'avvio dell'app.
- Esportazione CSV: la funzionalità `Export CSV` genera un file contenente statistiche per ogni asta (nome, ID, URL, timer, prezzo, strategy, click/resets, impostazioni per-asta).
- La griglia mostra tutte le aste monitorate con colonne: nome, timer, prezzo, strategia, click, resets, ultimo bidder.
- Operazioni disponibili per ogni riga: Avvia/Pausa, Stop, Puntata manuale, Rimuovi.
- Selezionando una riga si aprono i dettagli per-asta: log, lista utenti e impostazioni dedicate.
## Impostazioni principali
- `Timer Click` (0-8): secondo del countdown al quale si desidera effettuare il click (0 = 0.0-0.9s)
- `Max Clicks` / `Max Resets`: limiti operativi (0 = illimitato)
- `Min/Max Price`: evita puntate fuori dal range desiderato
Impostazioni e strategie consigliate
- `Timer Click` (0-8): secondo del countdown al quale inviare la puntata (0 = 0.0-0.9s)
- `Ritardo (ms)`: delay aggiuntivo prima di inviare il click
- `Multi-Click` (se disponibile): invia più tentativi paralleli per aumentare affidabilità
- Uso consigliato:
- Aste molteplici: impostare Timer basso e limiti di prezzo conservativi
- Asta ad alto valore: Timer 0-1, Ritardo 0ms, Multi-Click ON (se necessario)
## Interfaccia e controlli
- Griglia centrale: mostra tutte le aste monitorate con controlli per avviare, mettere in pausa, fermare e puntare manualmente.
- Log in tempo reale per ogni asta con dettagli di latenza, risposta server e fallimenti.
Dettagli tecnici
## Diagnostica ed esportazione
- Abilita log dettagliato prima di aprire issue o per analisi locali
- Usa `Export CSV` per conservare storici e confrontare strategie
- Mantieni screenshot del pannello log per report più chiari
Polling
- L'app utilizza polling HTTP adattivo: la frequenza delle richieste è regolata in base al timer dell'asta per bilanciare precisione e carico.
## FAQ e risoluzione dei problemi
- "Non vedo Click HTTP riuscito": assicurati di aver inserito correttamente il cookie dal browser e che la sessione sia valida.
- "Aste non rilevate": aggiungi manualmente gli URL o ID delle aste.
- "Il programma non si avvia": verifica .NET 8.0 Runtime installato e che il build sia andato a buon fine.
- "Click non funzionano": verifica Timer Click, limiti di prezzo, connessione internet e validità del cookie.
Invio puntate (Click HTTP)
- Le puntate sono effettuate tramite richieste HTTP GET verso l'endpoint di Bidoo (es.: `/bid.php?AID=...&sup=0&shock=0`).
- Le richieste includono il cookie di sessione fornito dall'utente.
- Latenza tipica: 10-30ms (variabile in base alla rete e al server remoto).
## Avvisi e responsabilità
- L'automazione potrebbe violare i Termini di Servizio di Bidoo. L'uso è a rischio e responsabilità dell'utente.
- Non salvare credenziali su disco: l'app non memorizza login, usa solo il cookie manuale.
- Cookie e dati di sessione rimangono in memoria e vengono rimossi alla chiusura dell'app.
Fallback e WebView2
- La versione corrente si concentra su polling e click via HTTP. Se il progetto integra WebView2 per altre funzionalità, l'invio attivo delle puntate è gestito via HTTP e non dipende dal rendering del browser.
## Changelog sintetico (ultime versioni)
- v3.0: Solo HTTP, nessun WebView2, cookie manuale, interfaccia unica su griglia
- v2.10: Click HTTP diretto, sincronizzazione cookie automatica, miglioramenti prestazionali
- v2.9: Persistenza automatica, UI improvements, export CSV
- v2.8: Polling adattivo e strategie ibride
Persistenza, esportazione e diagnostica
- Aste aggiunte manualmente sono salvate in: `%AppData%\AutoBidder\auctions.json` e ricaricate all'avvio.
- `Export CSV` consente di esportare statistiche per ogni asta: nome, ID, URL, timer, prezzo, click, resets, impostazioni.
- Abilitare log dettagliato per indagare problemi: il log registra latenza, risposte server e errori per-asta.
FAQ e risoluzione dei problemi
- "Non vedo Click HTTP riuscito": verifica che il cookie sia corretto e la sessione valida.
- "Aste non rilevate": aggiungi gli URL o gli ID manualmente nella griglia.
- "Il programma non si avvia": assicurati che .NET 8.0 sia installato e che il build sia andato a buon fine.
- "Click non funzionano": verifica Timer Click, limiti di prezzo, connessione di rete e validità del cookie.
Sicurezza e responsabilità
- L'uso di strumenti automatici può violare i Termini di Servizio di Bidoo. L'utente è responsabile dell'uso che fa dell'app.
- L'app non salva credenziali su disco. Gestisci i cookie in modo sicuro e non condividerli.
Supporto
## Supporto
- Repository privato Gitea: `https://192.168.30.23/Alby96/Mimante`
- Per problemi tecnici aprire issue nel repository privato (se abilitato) o contattare il manutentore del progetto.
- Per problemi tecnici aprire issue nel repository o contattare il manutentore del progetto.
---
Note per sviluppatori
Note tecniche per sviluppatori
- Progetto target: `.NET 8.0` (WPF)
- Aree chiave del codice:
- File e componenti principali:
- `Services\BidooApiClient.cs` — gestione Click HTTP e parsing risposte
- `Services\AuctionMonitor.cs` — loop di polling
- `Services\SessionManager.cs` — gestione cookie manuale
- `Utilities\PersistenceManager.cs`salvataggio/ricaricamento `auctions.json`
- `ViewModels\AuctionViewModel.cs` + XAML corrispondenti — visualizzazione e binding UI
- `Services\AuctionMonitor.cs` — loop di polling e logica di scheduling
- `Dialogs\SessionDialog.xaml` — dialog per l'inserimento manuale dei cookie
- `Utilities\PersistenceManager.cs`gestione `auctions.json`
- `ViewModels\AuctionViewModel.cs` — binding e stato delle righe nella griglia
## Contributi
- Questo repository è privato. Per contribuire, aprire PR verso branch `main` e seguire le convenzioni del progetto.
Contributi
- Repository privato: aprire PR verso `main` secondo le convenzioni del progetto.
Licenza
## Licenza
- Privato — non distribuire senza autorizzazione del proprietario.
Buona fortuna con le aste e usa AutoBidder responsabilmente.