f017ec0364
* Aggiunto `BooleanToOpacityConverter` per gestire opacità dinamica. * Introdotto nuovo sistema di timing con `BidBeforeDeadlineMs`. * Aggiunta opzione `CheckAuctionOpenBeforeBid` per maggiore sicurezza. * Implementato polling adattivo (10ms-1000ms) e cooldown di 800ms. * Migliorata gestione pulsanti globali con supporto `AUTO-START`/`AUTO-STOP`. * Fix per il tasto `Canc` e focus automatico sul `DataGrid`. * Fix per avvio singola asta senza necessità di "Avvia Tutti". * Aggiornati formati CSV/JSON/XML con nuovi campi. * Migliorata gestione cookie con endpoint unico `buy_bids.php`. * Miglioramenti UI/UX: tooltip, formattazione prezzi, feedback visivo. * Aggiornata documentazione e changelog per la versione 4.0.0.
292 lines
12 KiB
C#
292 lines
12 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using AutoBidder.Services;
|
|
using AutoBidder.Utilities;
|
|
|
|
namespace AutoBidder
|
|
{
|
|
/// <summary>
|
|
/// User info and banner management
|
|
/// </summary>
|
|
public partial class MainWindow
|
|
{
|
|
private System.Windows.Threading.DispatcherTimer _userBannerTimer;
|
|
private System.Windows.Threading.DispatcherTimer _userHtmlTimer;
|
|
|
|
private void InitializeUserInfoTimers()
|
|
{
|
|
// Timer per aggiornamento dati utente da HTML ogni 5 minuti (PRINCIPALE)
|
|
_userHtmlTimer = new System.Windows.Threading.DispatcherTimer();
|
|
_userHtmlTimer.Interval = TimeSpan.FromMinutes(5);
|
|
_userHtmlTimer.Tick += UserHtmlTimer_Tick;
|
|
_userHtmlTimer.Start();
|
|
|
|
// Timer per aggiornamento banner API ogni 10 minuti (SECONDARIO - fallback)
|
|
_userBannerTimer = new System.Windows.Threading.DispatcherTimer();
|
|
_userBannerTimer.Interval = TimeSpan.FromMinutes(10);
|
|
_userBannerTimer.Tick += UserBannerTimer_Tick;
|
|
_userBannerTimer.Start();
|
|
|
|
Log("[INFO] Timer info utente avviati (5min HTML principale, 10min API fallback)", LogLevel.Info);
|
|
}
|
|
|
|
private void SetUserBanner(string username, int? remainingBids)
|
|
{
|
|
try
|
|
{
|
|
var session = _auctionMonitor.GetSession();
|
|
|
|
if (!string.IsNullOrEmpty(username))
|
|
{
|
|
// === HEADER - 2 RIGHE ===
|
|
// Riga 1: Puntate + Credito
|
|
RemainingBidsText.Text = remainingBids?.ToString() ?? "0";
|
|
|
|
if (session?.ShopCredit > 0)
|
|
{
|
|
AuctionMonitor.ShopCreditText.Text = $"EUR {session.ShopCredit:F2}";
|
|
}
|
|
else
|
|
{
|
|
AuctionMonitor.ShopCreditText.Text = "EUR 0.00";
|
|
}
|
|
|
|
// Riga 2: Aste vinte (TODO: implementare)
|
|
BannerAsteDaRiscattare.Text = "0";
|
|
|
|
// === SIDEBAR - Pannello Utente ===
|
|
// Username
|
|
SidebarUsernameText.Text = username;
|
|
|
|
// ID Utente
|
|
if (session?.UserId > 0)
|
|
{
|
|
SidebarUserIdText.Text = $"ID: {session.UserId}";
|
|
SidebarUserIdText.Visibility = System.Windows.Visibility.Visible;
|
|
}
|
|
else
|
|
{
|
|
SidebarUserIdText.Visibility = System.Windows.Visibility.Collapsed;
|
|
}
|
|
|
|
// Email
|
|
if (!string.IsNullOrEmpty(session?.Email))
|
|
{
|
|
SidebarUserEmailText.Text = session.Email;
|
|
SidebarUserEmailText.Visibility = System.Windows.Visibility.Visible;
|
|
}
|
|
else
|
|
{
|
|
SidebarUserEmailText.Visibility = System.Windows.Visibility.Collapsed;
|
|
}
|
|
|
|
// Mostra il pannello sidebar
|
|
SidebarUserInfoPanel.Visibility = System.Windows.Visibility.Visible;
|
|
}
|
|
else
|
|
{
|
|
// Nascondi pannello sidebar
|
|
SidebarUserInfoPanel.Visibility = System.Windows.Visibility.Collapsed;
|
|
|
|
// Reset header
|
|
RemainingBidsText.Text = "0";
|
|
AuctionMonitor.ShopCreditText.Text = "EUR 0.00";
|
|
BannerAsteDaRiscattare.Text = "0";
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
private async void UserBannerTimer_Tick(object? sender, EventArgs e)
|
|
{
|
|
// Questo è ora il fallback secondario
|
|
await UpdateUserBannerInfoAsync();
|
|
}
|
|
|
|
private async void UserHtmlTimer_Tick(object? sender, EventArgs e)
|
|
{
|
|
// Questo è ora il metodo principale
|
|
await UpdateUserHtmlInfoAsync();
|
|
}
|
|
|
|
private async Task UpdateUserBannerInfoAsync()
|
|
{
|
|
try
|
|
{
|
|
Log("[INFO] Tentativo recupero info utente da API...", LogLevel.Info);
|
|
|
|
// Prova prima l'endpoint API
|
|
var success = await _auctionMonitor.UpdateUserInfoAsync();
|
|
|
|
if (success)
|
|
{
|
|
var session = _auctionMonitor.GetSession();
|
|
if (session != null && !string.IsNullOrEmpty(session.Username))
|
|
{
|
|
SetUserBanner(session.Username, session.RemainingBids);
|
|
Log($"[OK] Info utente API: {session.Username}, {session.RemainingBids} puntate", LogLevel.Info);
|
|
return; // Successo con API
|
|
}
|
|
else
|
|
{
|
|
Log($"[WARN] API ha risposto ma senza dati validi", LogLevel.Warn);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Log($"[WARN] API non ha risposto correttamente", LogLevel.Warn);
|
|
}
|
|
|
|
// Se API fallisce o non ha dati, usa HTML scraping come fallback
|
|
Log("[INFO] Tentativo fallback con HTML scraping...", LogLevel.Info);
|
|
var userData = await _auctionMonitor.GetUserDataFromHtmlAsync();
|
|
|
|
if (userData != null && !string.IsNullOrEmpty(userData.Username))
|
|
{
|
|
SetUserBanner(userData.Username, userData.RemainingBids);
|
|
Log($"[OK] Info utente HTML (fallback): {userData.Username}, {userData.RemainingBids} puntate", LogLevel.Info);
|
|
}
|
|
else
|
|
{
|
|
Log($"[ERROR] Impossibile aggiornare info utente - verifica cookie nelle Impostazioni", LogLevel.Warn);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log($"[ERROR] Errore aggiornamento banner utente: {ex.Message}", LogLevel.Warn);
|
|
Log($"[ERROR] StackTrace: {ex.StackTrace}", LogLevel.Warn);
|
|
}
|
|
}
|
|
|
|
private async Task UpdateUserHtmlInfoAsync()
|
|
{
|
|
try
|
|
{
|
|
Log("[INFO] Tentativo recupero dati utente da HTML...", LogLevel.Info);
|
|
|
|
// HTML scraping è il metodo PRINCIPALE (più affidabile)
|
|
var userData = await _auctionMonitor.GetUserDataFromHtmlAsync();
|
|
|
|
if (userData != null && !string.IsNullOrEmpty(userData.Username))
|
|
{
|
|
SetUserBanner(userData.Username, userData.RemainingBids);
|
|
Log($"[OK] Dati utente aggiornati via HTML: {userData.Username}, {userData.RemainingBids} puntate", LogLevel.Info);
|
|
}
|
|
else
|
|
{
|
|
// Se HTML fallisce, non fare nulla - il timer API proverà tra poco
|
|
Log($"[WARN] HTML scraping non ha restituito dati validi - verifica cookie nelle Impostazioni", LogLevel.Warn);
|
|
Log($"[WARN] Possibili cause: cookie scaduto, non autenticato, sito modificato", LogLevel.Warn);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log($"[ERROR] Errore aggiornamento dati HTML: {ex.Message}", LogLevel.Warn);
|
|
Log($"[ERROR] StackTrace: {ex.StackTrace}", LogLevel.Warn);
|
|
}
|
|
}
|
|
|
|
private void LoadSavedSession()
|
|
{
|
|
try
|
|
{
|
|
var session = SessionManager.LoadSession();
|
|
|
|
if (session != null && session.IsValid)
|
|
{
|
|
// Ripristina sessione nel monitor
|
|
if (!string.IsNullOrEmpty(session.CookieString))
|
|
{
|
|
_auctionMonitor.InitializeSessionWithCookie(session.CookieString, session.Username);
|
|
}
|
|
else if (!string.IsNullOrEmpty(session.AuthToken))
|
|
{
|
|
var cookieString = $"__stattrb={session.AuthToken}";
|
|
_auctionMonitor.InitializeSessionWithCookie(cookieString, session.Username);
|
|
}
|
|
|
|
// Show saved cookie in settings textbox
|
|
try
|
|
{
|
|
if (!string.IsNullOrEmpty(session.CookieString))
|
|
{
|
|
var m = System.Text.RegularExpressions.Regex.Match(session.CookieString, "__stattrb=([^;]+)");
|
|
if (m.Success && !session.CookieString.Contains(";"))
|
|
{
|
|
SettingsCookieTextBox.Text = m.Groups[1].Value;
|
|
}
|
|
else
|
|
{
|
|
SettingsCookieTextBox.Text = session.CookieString;
|
|
}
|
|
}
|
|
else if (!string.IsNullOrEmpty(session.AuthToken))
|
|
{
|
|
SettingsCookieTextBox.Text = session.AuthToken;
|
|
}
|
|
}
|
|
catch { }
|
|
|
|
StartButton.IsEnabled = true;
|
|
|
|
Log($"[OK] Sessione ripristinata per: {session.Username}");
|
|
|
|
// Verifica validità cookie (background) - USA HTML come metodo principale
|
|
Task.Run(async () =>
|
|
{
|
|
try
|
|
{
|
|
// Prova prima HTML scraping (più affidabile)
|
|
var htmlUser = await _auctionMonitor.GetUserDataFromHtmlAsync();
|
|
if (htmlUser != null && !string.IsNullOrEmpty(htmlUser.Username))
|
|
{
|
|
Dispatcher.Invoke(() =>
|
|
{
|
|
SetUserBanner(htmlUser.Username, htmlUser.RemainingBids);
|
|
Log($"[OK] Dati utente rilevati via HTML - Utente: {htmlUser.Username}, Puntate residue: {htmlUser.RemainingBids}");
|
|
});
|
|
return; // Successo con HTML
|
|
}
|
|
|
|
// Fallback: prova API
|
|
var success = await _auctionMonitor.UpdateUserInfoAsync();
|
|
var updatedSession = _auctionMonitor.GetSession();
|
|
|
|
Dispatcher.Invoke(() =>
|
|
{
|
|
if (success && updatedSession != null && !string.IsNullOrEmpty(updatedSession.Username))
|
|
{
|
|
SetUserBanner(updatedSession.Username, updatedSession.RemainingBids);
|
|
Log($"[OK] Cookie valido - Crediti disponibili: {updatedSession.RemainingBids}");
|
|
}
|
|
else
|
|
{
|
|
Log($"[WARN] Impossibile verificare sessione: verifica cookie nelle Impostazioni");
|
|
}
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Dispatcher.Invoke(() =>
|
|
{
|
|
Log($"[WARN] Errore verifica sessione: {ex.Message}");
|
|
});
|
|
}
|
|
});
|
|
}
|
|
else
|
|
{
|
|
Log("[INFO] Nessuna sessione salvata trovata");
|
|
Log("[INFO] Usa 'Configura Sessione' per inserire il cookie");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log($"[WARN] Errore caricamento sessione: {ex.Message}");
|
|
}
|
|
}
|
|
}
|
|
}
|