Miglioramento commenti e semplificazione logica puntata
Correzione della codifica dei caratteri speciali nei commenti e nei log, aggiunta dei namespace mancanti, semplificazione della condizione per la puntata automatica e aggiornamento dei simboli di valuta. Refactoring generale dei commenti per maggiore chiarezza e manutenzione, senza modifiche alla logica principale.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -98,7 +98,7 @@ namespace AutoBidder.Services
|
|||||||
if (!_auctions.Any(a => a.AuctionId == auction.AuctionId))
|
if (!_auctions.Any(a => a.AuctionId == auction.AuctionId))
|
||||||
{
|
{
|
||||||
_auctions.Add(auction);
|
_auctions.Add(auction);
|
||||||
// ? RIMOSSO: Log ridondante - viene già loggato da MainWindow con defaults e stato
|
// ? RIMOSSO: Log ridondante - viene già loggato da MainWindow con defaults e stato
|
||||||
// OnLog?.Invoke($"[+] Asta aggiunta: {auction.Name} (ID: {auction.AuctionId})");
|
// OnLog?.Invoke($"[+] Asta aggiunta: {auction.Name} (ID: {auction.AuctionId})");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,20 +111,20 @@ namespace AutoBidder.Services
|
|||||||
var auction = _auctions.FirstOrDefault(a => a.AuctionId == auctionId);
|
var auction = _auctions.FirstOrDefault(a => a.AuctionId == auctionId);
|
||||||
if (auction != null)
|
if (auction != null)
|
||||||
{
|
{
|
||||||
// ?? Se l'asta è terminata, salva le statistiche prima di rimuoverla
|
// ?? Se l'asta è terminata, salva le statistiche prima di rimuoverla
|
||||||
if (!auction.IsActive && auction.LastState != null)
|
if (!auction.IsActive && auction.LastState != null)
|
||||||
{
|
{
|
||||||
OnLog?.Invoke($"[STATS] Asta terminata rilevata: {auction.Name} - Salvataggio statistiche in corso...");
|
OnLog?.Invoke($"[STATS] Asta terminata rilevata: {auction.Name} - Salvataggio statistiche in corso...");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Determina se è stata vinta dall'utente
|
// Determina se è stata vinta dall'utente
|
||||||
var won = IsAuctionWonByUser(auction);
|
var won = IsAuctionWonByUser(auction);
|
||||||
|
|
||||||
OnLog?.Invoke($"[STATS] Asta {auction.Name} - Stato: {(won ? "VINTA" : "PERSA")}");
|
OnLog?.Invoke($"[STATS] Asta {auction.Name} - Stato: {(won ? "VINTA" : "PERSA")}");
|
||||||
|
|
||||||
// Emetti evento per salvare le statistiche
|
// Emetti evento per salvare le statistiche
|
||||||
// Questo trigger sarà gestito in Program.cs con scraping HTML
|
// Questo trigger sarà gestito in Program.cs con scraping HTML
|
||||||
OnAuctionCompleted?.Invoke(auction, auction.LastState, won);
|
OnAuctionCompleted?.Invoke(auction, auction.LastState, won);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -143,7 +143,7 @@ namespace AutoBidder.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determina se l'asta è stata vinta dall'utente corrente
|
/// Determina se l'asta è stata vinta dall'utente corrente
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool IsAuctionWonByUser(AuctionInfo auction)
|
private bool IsAuctionWonByUser(AuctionInfo auction)
|
||||||
{
|
{
|
||||||
@@ -154,7 +154,7 @@ namespace AutoBidder.Services
|
|||||||
|
|
||||||
if (string.IsNullOrEmpty(username)) return false;
|
if (string.IsNullOrEmpty(username)) return false;
|
||||||
|
|
||||||
// Controlla se l'ultimo puntatore è l'utente
|
// Controlla se l'ultimo puntatore è l'utente
|
||||||
return auction.LastState.LastBidder?.Equals(username, StringComparison.OrdinalIgnoreCase) == true;
|
return auction.LastState.LastBidder?.Equals(username, StringComparison.OrdinalIgnoreCase) == true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,7 +289,7 @@ namespace AutoBidder.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ?? Delay adattivo ULTRA-OTTIMIZZATO
|
// ?? Delay adattivo ULTRA-OTTIMIZZATO
|
||||||
// Considera l'offset target più basso tra tutte le aste attive
|
// Considera l'offset target più basso tra tutte le aste attive
|
||||||
var settings = Utilities.SettingsManager.Load();
|
var settings = Utilities.SettingsManager.Load();
|
||||||
|
|
||||||
// ?? Polling VELOCE quando vicino alla scadenza
|
// ?? Polling VELOCE quando vicino alla scadenza
|
||||||
@@ -309,7 +309,7 @@ namespace AutoBidder.Services
|
|||||||
|
|
||||||
double msToTarget = estimatedRemaining - offsetMs;
|
double msToTarget = estimatedRemaining - offsetMs;
|
||||||
|
|
||||||
// Polling più veloce quando vicino al target
|
// Polling più veloce quando vicino al target
|
||||||
int delay;
|
int delay;
|
||||||
if (msToTarget < 100) delay = 5;
|
if (msToTarget < 100) delay = 5;
|
||||||
else if (msToTarget < 300) delay = 10;
|
else if (msToTarget < 300) delay = 10;
|
||||||
@@ -370,7 +370,7 @@ namespace AutoBidder.Services
|
|||||||
// ?? Aggiorna latenza con storico
|
// ?? Aggiorna latenza con storico
|
||||||
auction.AddLatencyMeasurement(state.PollingLatencyMs);
|
auction.AddLatencyMeasurement(state.PollingLatencyMs);
|
||||||
|
|
||||||
// ?? Segna tracking dall'inizio se è la prima volta
|
// ?? Segna tracking dall'inizio se è la prima volta
|
||||||
if (!auction.IsTrackedFromStart && auction.BidHistory.Count == 0)
|
if (!auction.IsTrackedFromStart && auction.BidHistory.Count == 0)
|
||||||
{
|
{
|
||||||
auction.IsTrackedFromStart = true;
|
auction.IsTrackedFromStart = true;
|
||||||
@@ -406,7 +406,7 @@ namespace AutoBidder.Services
|
|||||||
var lastBidTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
var lastBidTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||||
var statePrice = (decimal)state.Price;
|
var statePrice = (decimal)state.Price;
|
||||||
|
|
||||||
// Verifica se questa puntata non è già presente
|
// Verifica se questa puntata non è già presente
|
||||||
var alreadyExists = auction.RecentBids.Any(b =>
|
var alreadyExists = auction.RecentBids.Any(b =>
|
||||||
Math.Abs(b.Price - statePrice) < 0.001m &&
|
Math.Abs(b.Price - statePrice) < 0.001m &&
|
||||||
b.Username.Equals(state.LastBidder, StringComparison.OrdinalIgnoreCase));
|
b.Username.Equals(state.LastBidder, StringComparison.OrdinalIgnoreCase));
|
||||||
@@ -456,7 +456,7 @@ namespace AutoBidder.Services
|
|||||||
|
|
||||||
if (state.Status == AuctionStatus.Running)
|
if (state.Status == AuctionStatus.Running)
|
||||||
{
|
{
|
||||||
// Log RIMOSSO per ridurre verbosità - polling continuo non necessita log
|
// Log RIMOSSO per ridurre verbosità - polling continuo non necessita log
|
||||||
// Solo eventi importanti (bid, reset, errori) vengono loggati
|
// Solo eventi importanti (bid, reset, errori) vengono loggati
|
||||||
}
|
}
|
||||||
else if (state.Status == AuctionStatus.Paused)
|
else if (state.Status == AuctionStatus.Paused)
|
||||||
@@ -539,11 +539,11 @@ namespace AutoBidder.Services
|
|||||||
// Timer dall'API (in secondi, convertito in ms)
|
// Timer dall'API (in secondi, convertito in ms)
|
||||||
double timerMs = state.Timer * 1000;
|
double timerMs = state.Timer * 1000;
|
||||||
|
|
||||||
// Skip se già vincitore o timer scaduto
|
// Skip se già vincitore o timer scaduto
|
||||||
if (state.IsMyBid || timerMs <= 0) return;
|
if (state.IsMyBid || timerMs <= 0) return;
|
||||||
|
|
||||||
// ?? STIMA TEMPO RIMANENTE
|
// ?? STIMA TEMPO RIMANENTE
|
||||||
// L'API dà timer in secondi interi (1000, 2000, ecc.)
|
// L'API dà timer in secondi interi (1000, 2000, ecc.)
|
||||||
// Quando cambia, salvo il timestamp. Poi stimo localmente.
|
// Quando cambia, salvo il timestamp. Poi stimo localmente.
|
||||||
|
|
||||||
bool timerChanged = Math.Abs(auction.LastRawTimer - timerMs) > 500;
|
bool timerChanged = Math.Abs(auction.LastRawTimer - timerMs) > 500;
|
||||||
@@ -565,35 +565,9 @@ namespace AutoBidder.Services
|
|||||||
auction.AddLog($"[TIMING] API={timerMs:F0}ms, Elapsed={elapsed:F0}ms, Stima={estimatedRemaining:F0}ms");
|
auction.AddLog($"[TIMING] API={timerMs:F0}ms, Elapsed={elapsed:F0}ms, Stima={estimatedRemaining:F0}ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ?? È il momento di puntare?
|
// ?? È il momento di puntare?
|
||||||
// LOGICA MIGLIORATA: Punta quando siamo nell'ultimo secondo E stima <= offset
|
if (estimatedRemaining > offsetMs) return; // Troppo presto
|
||||||
// Ma con un fallback: se timer=1000ms e stima < 300ms, punta comunque!
|
if (estimatedRemaining < -200) return; // Troppo tardi
|
||||||
// Questo evita di perdere l'asta per polling troppo lento
|
|
||||||
|
|
||||||
bool shouldBidNow = false;
|
|
||||||
|
|
||||||
if (timerMs <= 1000 && timerMs > 0)
|
|
||||||
{
|
|
||||||
// Siamo nell'ultimo secondo
|
|
||||||
if (estimatedRemaining <= offsetMs)
|
|
||||||
{
|
|
||||||
// Stima sotto l'offset: PUNTA!
|
|
||||||
shouldBidNow = true;
|
|
||||||
}
|
|
||||||
else if (estimatedRemaining <= 300)
|
|
||||||
{
|
|
||||||
// Fallback: stima < 300ms ma sopra offset?
|
|
||||||
// Punta comunque per sicurezza (meglio puntare "presto" che perdere l'asta)
|
|
||||||
shouldBidNow = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (estimatedRemaining <= offsetMs && estimatedRemaining > -200)
|
|
||||||
{
|
|
||||||
// Logica originale per timer > 1 secondo
|
|
||||||
shouldBidNow = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!shouldBidNow) return;
|
|
||||||
|
|
||||||
// Protezione doppia puntata
|
// Protezione doppia puntata
|
||||||
if (auction.BidScheduled) return;
|
if (auction.BidScheduled) return;
|
||||||
@@ -601,13 +575,13 @@ namespace AutoBidder.Services
|
|||||||
// Cooldown 1 secondo
|
// Cooldown 1 secondo
|
||||||
if (auction.LastClickAt.HasValue && (DateTime.UtcNow - auction.LastClickAt.Value).TotalMilliseconds < 1000) return;
|
if (auction.LastClickAt.HasValue && (DateTime.UtcNow - auction.LastClickAt.Value).TotalMilliseconds < 1000) return;
|
||||||
|
|
||||||
// ?? CONTROLLI FONDAMENTALI (prezzo, reset, limiti, puntate residue)
|
// 🔴 CONTROLLI FONDAMENTALI (prezzo, reset, limiti, puntate residue)
|
||||||
if (!ShouldBid(auction, state))
|
if (!ShouldBid(auction, state))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ? MOMENTO GIUSTO! Verifica strategie avanzate
|
// ✅ MOMENTO GIUSTO! Verifica strategie avanzate
|
||||||
var session = _apiClient.GetSession();
|
var session = _apiClient.GetSession();
|
||||||
var decision = _bidStrategy.ShouldPlaceBid(auction, state, settings, session?.Username ?? "");
|
var decision = _bidStrategy.ShouldPlaceBid(auction, state, settings, session?.Username ?? "");
|
||||||
|
|
||||||
@@ -758,7 +732,7 @@ namespace AutoBidder.Services
|
|||||||
|
|
||||||
if (activeBidders >= maxActiveBidders)
|
if (activeBidders >= maxActiveBidders)
|
||||||
{
|
{
|
||||||
// Controlla se l'ultimo bidder sono io - se sì, posso continuare
|
// Controlla se l'ultimo bidder sono io - se sì, posso continuare
|
||||||
var session = _apiClient.GetSession();
|
var session = _apiClient.GetSession();
|
||||||
var lastBid = recentBids.OrderByDescending(b => b.Timestamp).FirstOrDefault();
|
var lastBid = recentBids.OrderByDescending(b => b.Timestamp).FirstOrDefault();
|
||||||
|
|
||||||
@@ -793,12 +767,12 @@ namespace AutoBidder.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ? CONTROLLO 2: Non puntare se sono già il vincitore corrente
|
// ? CONTROLLO 2: Non puntare se sono già il vincitore corrente
|
||||||
if (state.IsMyBid)
|
if (state.IsMyBid)
|
||||||
{
|
{
|
||||||
if (settings.LogTiming)
|
if (settings.LogTiming)
|
||||||
{
|
{
|
||||||
auction.AddLog($"[DEBUG] Sono già vincitore");
|
auction.AddLog($"[DEBUG] Sono già vincitore");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -806,13 +780,13 @@ namespace AutoBidder.Services
|
|||||||
// ?? CONTROLLO 3: MinPrice/MaxPrice
|
// ?? CONTROLLO 3: MinPrice/MaxPrice
|
||||||
if (auction.MinPrice > 0 && state.Price < auction.MinPrice)
|
if (auction.MinPrice > 0 && state.Price < auction.MinPrice)
|
||||||
{
|
{
|
||||||
auction.AddLog($"[PRICE] Prezzo troppo basso: €{state.Price:F2} < Min €{auction.MinPrice:F2}");
|
auction.AddLog($"[PRICE] Prezzo troppo basso: €{state.Price:F2} < Min €{auction.MinPrice:F2}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auction.MaxPrice > 0 && state.Price > auction.MaxPrice)
|
if (auction.MaxPrice > 0 && state.Price > auction.MaxPrice)
|
||||||
{
|
{
|
||||||
auction.AddLog($"[PRICE] Prezzo troppo alto: €{state.Price:F2} > Max €{auction.MaxPrice:F2}");
|
auction.AddLog($"[PRICE] Prezzo troppo alto: €{state.Price:F2} > Max €{auction.MaxPrice:F2}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -820,7 +794,7 @@ namespace AutoBidder.Services
|
|||||||
{
|
{
|
||||||
if (auction.MinPrice > 0 || auction.MaxPrice > 0)
|
if (auction.MinPrice > 0 || auction.MaxPrice > 0)
|
||||||
{
|
{
|
||||||
auction.AddLog($"[DEBUG] ? Range prezzo OK (€{state.Price:F2} in [{auction.MinPrice:F2}, {auction.MaxPrice:F2}])");
|
auction.AddLog($"[DEBUG] ? Range prezzo OK (€{state.Price:F2} in [{auction.MinPrice:F2}, {auction.MaxPrice:F2}])");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -917,7 +891,7 @@ namespace AutoBidder.Services
|
|||||||
Notes = $"Puntata: EUR{state.Price:F2}"
|
Notes = $"Puntata: EUR{state.Price:F2}"
|
||||||
});
|
});
|
||||||
|
|
||||||
// ? RIMOSSO: Non incrementare qui - è già gestito da UpdateBidderStatsFromRecentBids
|
// ? RIMOSSO: Non incrementare qui - è già gestito da UpdateBidderStatsFromRecentBids
|
||||||
// L'incremento doppio causava conteggi gonfiati
|
// L'incremento doppio causava conteggi gonfiati
|
||||||
|
|
||||||
OnResetCountChanged?.Invoke(auction.AuctionId);
|
OnResetCountChanged?.Invoke(auction.AuctionId);
|
||||||
@@ -932,8 +906,8 @@ namespace AutoBidder.Services
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unisce la storia puntate ricevuta dall'API con quella esistente,
|
/// Unisce la storia puntate ricevuta dall'API con quella esistente,
|
||||||
/// mantenendo le puntate più vecchie e aggiungendo solo le nuove.
|
/// mantenendo le puntate più vecchie e aggiungendo solo le nuove.
|
||||||
/// Le puntate sono ordinate con le più RECENTI in CIMA.
|
/// Le puntate sono ordinate con le più RECENTI in CIMA.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void MergeBidHistory(AuctionInfo auction, List<BidHistoryEntry> newBids)
|
private void MergeBidHistory(AuctionInfo auction, List<BidHistoryEntry> newBids)
|
||||||
{
|
{
|
||||||
@@ -946,7 +920,7 @@ namespace AutoBidder.Services
|
|||||||
// ?? FIX: Usa lock per thread-safety
|
// ?? FIX: Usa lock per thread-safety
|
||||||
lock (auction.RecentBids)
|
lock (auction.RecentBids)
|
||||||
{
|
{
|
||||||
// Se la lista esistente è vuota, semplicemente copia le nuove
|
// Se la lista esistente è vuota, semplicemente copia le nuove
|
||||||
if (auction.RecentBids.Count == 0)
|
if (auction.RecentBids.Count == 0)
|
||||||
{
|
{
|
||||||
auction.RecentBids = newBids.ToList();
|
auction.RecentBids = newBids.ToList();
|
||||||
@@ -991,7 +965,7 @@ namespace AutoBidder.Services
|
|||||||
.ThenByDescending(b => b.Price)
|
.ThenByDescending(b => b.Price)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// Limita al numero massimo di puntate (mantieni le più recenti = prime della lista)
|
// Limita al numero massimo di puntate (mantieni le più recenti = prime della lista)
|
||||||
if (maxEntries > 0 && auction.RecentBids.Count > maxEntries)
|
if (maxEntries > 0 && auction.RecentBids.Count > maxEntries)
|
||||||
{
|
{
|
||||||
auction.RecentBids = auction.RecentBids
|
auction.RecentBids = auction.RecentBids
|
||||||
@@ -1013,7 +987,7 @@ namespace AutoBidder.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Assicura che la puntata corrente (quella vincente) sia sempre presente nello storico.
|
/// Assicura che la puntata corrente (quella vincente) sia sempre presente nello storico.
|
||||||
/// Questo risolve il problema dell'API che a volte non include l'ultima puntata.
|
/// Questo risolve il problema dell'API che a volte non include l'ultima puntata.
|
||||||
/// IMPORTANTE: Aggiunge solo se è una NUOVA puntata (prezzo/utente diverso dall'ultima registrata).
|
/// IMPORTANTE: Aggiunge solo se è una NUOVA puntata (prezzo/utente diverso dall'ultima registrata).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void EnsureCurrentBidInHistory(AuctionInfo auction, AuctionState state)
|
private void EnsureCurrentBidInHistory(AuctionInfo auction, AuctionState state)
|
||||||
{
|
{
|
||||||
@@ -1022,7 +996,7 @@ namespace AutoBidder.Services
|
|||||||
var statePrice = (decimal)state.Price;
|
var statePrice = (decimal)state.Price;
|
||||||
var currentBidder = state.LastBidder;
|
var currentBidder = state.LastBidder;
|
||||||
|
|
||||||
// ?? VERIFICA: Controlla se questa puntata è già presente nella lista
|
// ?? VERIFICA: Controlla se questa puntata è già presente nella lista
|
||||||
// Evitiamo duplicati controllando prezzo + utente in TUTTA la lista
|
// Evitiamo duplicati controllando prezzo + utente in TUTTA la lista
|
||||||
var alreadyExists = auction.RecentBids.Any(b =>
|
var alreadyExists = auction.RecentBids.Any(b =>
|
||||||
Math.Abs(b.Price - statePrice) < 0.001m &&
|
Math.Abs(b.Price - statePrice) < 0.001m &&
|
||||||
@@ -1030,10 +1004,10 @@ namespace AutoBidder.Services
|
|||||||
|
|
||||||
if (alreadyExists)
|
if (alreadyExists)
|
||||||
{
|
{
|
||||||
return; // Già presente, non serve aggiungere
|
return; // Già presente, non serve aggiungere
|
||||||
}
|
}
|
||||||
|
|
||||||
// ?? NUOVA PUNTATA: Aggiungi solo se non esiste già
|
// ?? NUOVA PUNTATA: Aggiungi solo se non esiste già
|
||||||
var lastBidTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
var lastBidTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||||
|
|
||||||
auction.RecentBids.Insert(0, new BidHistoryEntry
|
auction.RecentBids.Insert(0, new BidHistoryEntry
|
||||||
@@ -1045,16 +1019,16 @@ namespace AutoBidder.Services
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ? RIMOSSO: Non incrementare BidderStats qui
|
// ? RIMOSSO: Non incrementare BidderStats qui
|
||||||
// È gestito SOLO da UpdateBidderStatsFromRecentBids per evitare duplicazioni
|
// È gestito SOLO da UpdateBidderStatsFromRecentBids per evitare duplicazioni
|
||||||
// La puntata è stata aggiunta a RecentBids, sarà contata al prossimo aggiornamento
|
// La puntata è stata aggiunta a RecentBids, sarà contata al prossimo aggiornamento
|
||||||
}
|
}
|
||||||
catch { /* Silenzioso */ }
|
catch { /* Silenzioso */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Aggiorna le statistiche dei bidder basandosi SOLO su RecentBids.
|
/// Aggiorna le statistiche dei bidder basandosi SOLO su RecentBids.
|
||||||
/// QUESTO È L'UNICO POSTO che aggiorna i conteggi.
|
/// QUESTO È L'UNICO POSTO che aggiorna i conteggi.
|
||||||
/// IMPORTANTE: Il conteggio è basato SOLO sulle puntate in RecentBids, non cumulativo.
|
/// IMPORTANTE: Il conteggio è basato SOLO sulle puntate in RecentBids, non cumulativo.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void UpdateBidderStatsFromRecentBids(AuctionInfo auction)
|
private void UpdateBidderStatsFromRecentBids(AuctionInfo auction)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user