284 lines
9.0 KiB
C++
284 lines
9.0 KiB
C++
|
|
// Fill out your copyright notice in the Description page of Project Settings.
|
|||
|
|
|
|||
|
|
|
|||
|
|
#include "Widget/SDTFluxRaceResultWidget.h"
|
|||
|
|
|
|||
|
|
#include "DTFluxRaceResultModule.h"
|
|||
|
|
#include "HttpModule.h"
|
|||
|
|
#include "IWebBrowserCookieManager.h"
|
|||
|
|
#include "IWebBrowserWindow.h"
|
|||
|
|
#include "SlateOptMacros.h"
|
|||
|
|
#include "WebBrowserModule.h"
|
|||
|
|
#include "Interfaces/IHttpRequest.h"
|
|||
|
|
#include "Interfaces/IHttpResponse.h"
|
|||
|
|
|
|||
|
|
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
|||
|
|
|
|||
|
|
void SDTFluxRaceResultWidget::Construct(const FArguments& InArgs)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
FWebBrowserInitSettings browserInitSettings = FWebBrowserInitSettings();
|
|||
|
|
|
|||
|
|
IWebBrowserModule::Get().CustomInitialize(browserInitSettings);
|
|||
|
|
WindowSettings.InitialURL = TEXT("about:blank");
|
|||
|
|
WindowSettings.BrowserFrameRate = 25;
|
|||
|
|
|
|||
|
|
if (IWebBrowserModule::IsAvailable() && IWebBrowserModule::Get().IsWebModuleAvailable())
|
|||
|
|
{
|
|||
|
|
IWebBrowserSingleton* WebBrowserSingleton = IWebBrowserModule::Get().GetSingleton();
|
|||
|
|
Browser = WebBrowserSingleton->CreateBrowserWindow(WindowSettings);
|
|||
|
|
// Browser->OnLoadUrl().BindRaw(this, &SDTFluxRaceResultWidget::OnLoadOverride);
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
ChildSlot
|
|||
|
|
[
|
|||
|
|
SNew(SBox)
|
|||
|
|
.Padding(5.0f)
|
|||
|
|
[
|
|||
|
|
SNew(SBorder)
|
|||
|
|
.BorderImage(FCoreStyle::Get().GetBrush("ToolPanel.GroupBorder"))
|
|||
|
|
[
|
|||
|
|
SNew(SVerticalBox)
|
|||
|
|
+ SVerticalBox::Slot()
|
|||
|
|
[
|
|||
|
|
SAssignNew(WebBrowser, SWebBrowser, Browser)
|
|||
|
|
.ShowControls(true)
|
|||
|
|
.SupportsTransparency(true)
|
|||
|
|
.OnUrlChanged(this, &SDTFluxRaceResultWidget::OnUrlChanged)
|
|||
|
|
.OnBeforeNavigation(this, &SDTFluxRaceResultWidget::OnBeforeNavigation)
|
|||
|
|
.OnLoadCompleted(FSimpleDelegate::CreateRaw(this, &SDTFluxRaceResultWidget::OnLoadCompleted))
|
|||
|
|
.OnLoadError(FSimpleDelegate::CreateRaw(this, &SDTFluxRaceResultWidget::OnLoadError))
|
|||
|
|
.OnLoadStarted(FSimpleDelegate::CreateRaw(this, &SDTFluxRaceResultWidget::OnLoadStarted))
|
|||
|
|
.ShowErrorMessage(true)
|
|||
|
|
.ShowAddressBar(true)
|
|||
|
|
]
|
|||
|
|
]
|
|||
|
|
]
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SDTFluxRaceResultWidget::OnCookieSet(bool bSuccess)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
void SDTFluxRaceResultWidget::LoadContentViaHTTP()
|
|||
|
|
{
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Log, TEXT("Loading initial content via HTTP: %s"), *RaceResultUrl);
|
|||
|
|
LoadSpecificURL(RaceResultUrl);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
void SDTFluxRaceResultWidget::LoadSpecificURL(const FString& Url)
|
|||
|
|
{
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Log, TEXT("Loading via HTTP: %s"), *Url);
|
|||
|
|
|
|||
|
|
// Créer la requête HTTP
|
|||
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Request = FHttpModule::Get().CreateRequest();
|
|||
|
|
|
|||
|
|
// Ajouter l'authentification Basic pour TOUTES les requêtes
|
|||
|
|
FString Credentials = Username + TEXT(":") + Password;
|
|||
|
|
FString EncodedCredentials = FBase64::Encode(Credentials);
|
|||
|
|
|
|||
|
|
Request->SetURL(Url);
|
|||
|
|
Request->SetVerb("GET");
|
|||
|
|
Request->SetHeader("Authorization", "Basic " + EncodedCredentials);
|
|||
|
|
Request->SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
|
|||
|
|
Request->SetHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
|||
|
|
Request->SetHeader("Accept-Language", "en-US,en;q=0.5");
|
|||
|
|
Request->SetHeader("Accept-Encoding", "gzip, deflate");
|
|||
|
|
Request->SetHeader("Connection", "keep-alive");
|
|||
|
|
|
|||
|
|
Request->OnProcessRequestComplete().BindRaw(this, &SDTFluxRaceResultWidget::OnHTTPContentLoaded);
|
|||
|
|
Request->ProcessRequest();
|
|||
|
|
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Log, TEXT("HTTP request sent with Basic Auth"));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SDTFluxRaceResultWidget::OnHTTPContentLoaded(TSharedPtr<IHttpRequest> Request,
|
|||
|
|
TSharedPtr<IHttpResponse> HttpResponse, bool bWasSuccessful)
|
|||
|
|
{
|
|||
|
|
if (bWasSuccessful && HttpResponse.IsValid())
|
|||
|
|
{
|
|||
|
|
int32 ResponseCode = HttpResponse->GetResponseCode();
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Log, TEXT("HTTP Response Code: %d"), ResponseCode);
|
|||
|
|
|
|||
|
|
if (ResponseCode == 200)
|
|||
|
|
{
|
|||
|
|
FString Content = HttpResponse->GetContentAsString();
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Log, TEXT("Content loaded successfully, size: %d characters"), Content.Len());
|
|||
|
|
|
|||
|
|
// Traiter le contenu HTML
|
|||
|
|
FString ProcessedContent = ProcessHTMLContent(Content, Request->GetURL());
|
|||
|
|
|
|||
|
|
// Charger le contenu dans le browser via LoadString
|
|||
|
|
if (Browser.IsValid())
|
|||
|
|
{
|
|||
|
|
Browser->LoadString(ProcessedContent, Request->GetURL());
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Log, TEXT("Content loaded into browser"));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (ResponseCode == 401)
|
|||
|
|
{
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Error, TEXT("Authentication failed - 401 Unauthorized. Check your credentials."));
|
|||
|
|
}
|
|||
|
|
else if (ResponseCode == 403)
|
|||
|
|
{
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Error, TEXT("Access forbidden - 403 Forbidden"));
|
|||
|
|
}
|
|||
|
|
else if (ResponseCode == 404)
|
|||
|
|
{
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Error, TEXT("Page not found - 404 Not Found"));
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Error, TEXT("HTTP request failed with code: %d"), ResponseCode);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Error, TEXT("HTTP request failed completely"));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SDTFluxRaceResultWidget::OnLoadOverride()
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
void SDTFluxRaceResultWidget::OnUrlChanged(const FText& NewUrl)
|
|||
|
|
{
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Log, TEXT("URL changed to: %s"), *NewUrl.ToString());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FString SDTFluxRaceResultWidget::ProcessHTMLContent(const FString& Content, const FString& BaseUrl)
|
|||
|
|
{
|
|||
|
|
FString ProcessedContent = Content;
|
|||
|
|
|
|||
|
|
// Extraire le domaine de base
|
|||
|
|
FString BaseDomain = ExtractDomain(BaseUrl);
|
|||
|
|
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Log, TEXT("Processing HTML content, base domain: %s"), *BaseDomain);
|
|||
|
|
|
|||
|
|
// Convertir tous les liens relatifs en liens absolus
|
|||
|
|
ProcessedContent = ProcessedContent.Replace(TEXT("src=\"/"), *FString::Printf(TEXT("src=\"%s/"), *BaseDomain));
|
|||
|
|
ProcessedContent = ProcessedContent.Replace(TEXT("href=\"/"), *FString::Printf(TEXT("href=\"%s/"), *BaseDomain));
|
|||
|
|
ProcessedContent = ProcessedContent.Replace(TEXT("src='/"), *FString::Printf(TEXT("src='%s/"), *BaseDomain));
|
|||
|
|
ProcessedContent = ProcessedContent.Replace(TEXT("href='/"), *FString::Printf(TEXT("href='%s/"), *BaseDomain));
|
|||
|
|
|
|||
|
|
// Gérer les liens relatifs avec ./
|
|||
|
|
ProcessedContent = ProcessedContent.Replace(TEXT("src=\"./"), *FString::Printf(TEXT("src=\"%s/"), *BaseDomain));
|
|||
|
|
ProcessedContent = ProcessedContent.Replace(TEXT("href=\"./"), *FString::Printf(TEXT("href=\"%s/"), *BaseDomain));
|
|||
|
|
|
|||
|
|
// Ajouter une balise base pour aider avec les liens relatifs restants
|
|||
|
|
FString BaseTag = FString::Printf(TEXT("<base href=\"%s/\">"), *BaseDomain);
|
|||
|
|
if (ProcessedContent.Contains(TEXT("<head>")))
|
|||
|
|
{
|
|||
|
|
FString HeadReplacement = TEXT("<head>") + BaseTag;
|
|||
|
|
ProcessedContent = ProcessedContent.Replace(TEXT("<head>"), *HeadReplacement);
|
|||
|
|
}
|
|||
|
|
else if (ProcessedContent.Contains(TEXT("<HEAD>")))
|
|||
|
|
{
|
|||
|
|
FString HeadReplacement = TEXT("<HEAD>") + BaseTag;
|
|||
|
|
ProcessedContent = ProcessedContent.Replace(TEXT("<HEAD>"), *HeadReplacement);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Log, TEXT("HTML content processed"));
|
|||
|
|
return ProcessedContent;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
FString SDTFluxRaceResultWidget::ExtractDomain(const FString& Url)
|
|||
|
|
{
|
|||
|
|
FString Domain = Url;
|
|||
|
|
|
|||
|
|
// Enlever le protocole
|
|||
|
|
if (Url.StartsWith(TEXT("https://")))
|
|||
|
|
{
|
|||
|
|
Domain = Url.Mid(8);
|
|||
|
|
}
|
|||
|
|
else if (Url.StartsWith(TEXT("http://")))
|
|||
|
|
{
|
|||
|
|
Domain = Url.Mid(7);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Trouver le premier slash (début du path)
|
|||
|
|
int32 SlashIndex;
|
|||
|
|
if (Domain.FindChar(TEXT('/'), SlashIndex))
|
|||
|
|
{
|
|||
|
|
Domain = Url.Left(Url.Len() - (Domain.Len() - SlashIndex));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Enlever le port si présent
|
|||
|
|
FString DomainPart = Domain;
|
|||
|
|
if (Domain.StartsWith(TEXT("https://")))
|
|||
|
|
{
|
|||
|
|
DomainPart = Domain.Mid(8);
|
|||
|
|
}
|
|||
|
|
else if (Domain.StartsWith(TEXT("http://")))
|
|||
|
|
{
|
|||
|
|
DomainPart = Domain.Mid(7);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int32 ColonIndex;
|
|||
|
|
if (DomainPart.FindChar(TEXT(':'), ColonIndex))
|
|||
|
|
{
|
|||
|
|
Domain = Domain.Left(Domain.Len() - (DomainPart.Len() - ColonIndex));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return Domain;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool SDTFluxRaceResultWidget::OnBeforeNavigation(const FString& Url, const FWebNavigationRequest& Request)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Log, TEXT("Loading via HTTP: %s"), *Url);
|
|||
|
|
|
|||
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> HTTPRequest = FHttpModule::Get().CreateRequest();
|
|||
|
|
|
|||
|
|
// Authentification pour toutes les requêtes
|
|||
|
|
FString Credentials = Username + TEXT(":") + Password;
|
|||
|
|
FString EncodedCredentials = FBase64::Encode(Credentials);
|
|||
|
|
|
|||
|
|
HTTPRequest->SetURL(RaceResultUrl);
|
|||
|
|
HTTPRequest->SetVerb("GET");
|
|||
|
|
HTTPRequest->SetHeader("Authorization", "Basic " + EncodedCredentials);
|
|||
|
|
HTTPRequest->SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
|
|||
|
|
HTTPRequest->SetHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
|
|||
|
|
|
|||
|
|
HTTPRequest->OnProcessRequestComplete().BindRaw(this, &SDTFluxRaceResultWidget::OnHTTPContentLoaded);
|
|||
|
|
HTTPRequest->ProcessRequest();
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SDTFluxRaceResultWidget::OnLoadCompleted()
|
|||
|
|
{
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Log, TEXT("Load Completed"));
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SDTFluxRaceResultWidget::OnLoadStarted()
|
|||
|
|
{
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Log, TEXT("Load Started"));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SDTFluxRaceResultWidget::OnLoadError()
|
|||
|
|
{
|
|||
|
|
UE_LOG(logDTFluxRaceResult, Log, TEXT("Load Error"));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SDTFluxRaceResultWidget::OnBeforeResourceLoad(FString Url, FString ResourceType, FContextRequestHeaders& AdditionalHeaders, const bool AllowUserCredentials)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SDTFluxRaceResultWidget::SetupBasicAuth()
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|