2025-06-29 19:04:36 +02:00
|
|
|
|
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "DTFluxCoreSubsystem.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "DTFluxCoreSubsystemModule.h"
|
|
|
|
|
|
#include "DTFluxGeneralSettings.h"
|
2025-07-09 03:27:23 +02:00
|
|
|
|
#include "DTFluxPursuitManager.h"
|
2025-07-03 17:28:51 +02:00
|
|
|
|
#include "FileHelpers.h"
|
2025-06-29 19:04:36 +02:00
|
|
|
|
#include "Assets/DTFluxModelAsset.h"
|
|
|
|
|
|
#include "Subsystems/DTFluxNetworkSubsystem.h"
|
2025-07-11 23:45:23 +02:00
|
|
|
|
#include "Struct/DTFluxServerResponseStruct.h"
|
2025-07-03 17:28:51 +02:00
|
|
|
|
#include "UObject/SavePackage.h"
|
2025-06-29 19:04:36 +02:00
|
|
|
|
|
|
|
|
|
|
void UDTFluxCoreSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
|
|
|
|
|
{
|
|
|
|
|
|
Super::Initialize(Collection);
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Log, TEXT("[UDTFluxCoreSubsystem] Initializing..."));
|
2025-07-08 16:50:31 +02:00
|
|
|
|
if (!DataStorage)
|
2025-06-29 19:04:36 +02:00
|
|
|
|
{
|
|
|
|
|
|
const UDTFluxGeneralSettings* GeneralSettings = GetDefault<UDTFluxGeneralSettings>();
|
|
|
|
|
|
TSoftObjectPtr<UDTFluxModelAsset> ModelAsset = GeneralSettings->ModelAsset;
|
2025-07-04 01:13:07 +02:00
|
|
|
|
DataStorage = ModelAsset.LoadSynchronous();
|
2025-07-08 16:50:31 +02:00
|
|
|
|
if (!DataStorage)
|
2025-07-03 17:28:51 +02:00
|
|
|
|
{
|
2025-07-08 16:50:31 +02:00
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DataStorage Not Valid"));
|
2025-07-03 17:28:51 +02:00
|
|
|
|
}
|
2025-06-29 19:04:36 +02:00
|
|
|
|
}
|
|
|
|
|
|
//TODO REMOVE This as it's only for testing purpose
|
2025-07-03 17:28:51 +02:00
|
|
|
|
NetworkSubsystem = GEngine->GetEngineSubsystem<UDTFluxNetworkSubsystem>();
|
2025-07-08 16:50:31 +02:00
|
|
|
|
if (NetworkSubsystem->WsStatus != EDTFluxConnectionStatus::Connected)
|
2025-06-29 19:04:36 +02:00
|
|
|
|
{
|
|
|
|
|
|
RegisterDelegates();
|
|
|
|
|
|
}
|
2025-07-11 13:09:18 +02:00
|
|
|
|
PursuitManager = NewObject<UDTFluxPursuitManager>(this);
|
2025-06-29 19:04:36 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void UDTFluxCoreSubsystem::Deinitialize()
|
|
|
|
|
|
{
|
|
|
|
|
|
Super::Deinitialize();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-03 17:28:51 +02:00
|
|
|
|
void UDTFluxCoreSubsystem::SaveDataStorage()
|
|
|
|
|
|
{
|
2025-07-08 16:50:31 +02:00
|
|
|
|
if (!DataStorage->MarkPackageDirty())
|
2025-07-04 01:13:07 +02:00
|
|
|
|
{
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Unable to make package dirty !!!"))
|
|
|
|
|
|
}
|
2025-07-08 16:50:31 +02:00
|
|
|
|
if (DataStorage)
|
2025-07-03 17:28:51 +02:00
|
|
|
|
{
|
2025-07-04 01:13:07 +02:00
|
|
|
|
UEditorLoadingAndSavingUtils::SavePackages({DataStorage->GetPackage()}, true);
|
2025-07-03 17:28:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-11 23:45:23 +02:00
|
|
|
|
void UDTFluxCoreSubsystem::ProcessTrackedResponse(FDTFluxServerResponse& InResponse)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (InResponse.GetResponseType())
|
|
|
|
|
|
{
|
|
|
|
|
|
case EDTFluxApiDataType::ContestRanking:
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxContestRankings Rankings;
|
|
|
|
|
|
if (InResponse.ParseContestRanking(Rankings))
|
|
|
|
|
|
{
|
2025-07-12 09:41:15 +02:00
|
|
|
|
OnContestRankings.Broadcast(Rankings.ContestId, Rankings);
|
2025-07-11 23:45:23 +02:00
|
|
|
|
ProcessContestRanking(Rankings);
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("ContestRanking added for Contest %s"),
|
|
|
|
|
|
*Rankings.ContestName);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("Unable to parse ContestRanking"));
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
case EDTFluxApiDataType::StageRanking:
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxStageRankings Rankings;
|
|
|
|
|
|
if (InResponse.ParseStageRanking(Rankings))
|
|
|
|
|
|
{
|
2025-07-12 09:41:15 +02:00
|
|
|
|
FDTFluxStageKey StageKey(Rankings.ContestId, Rankings.StageId);
|
|
|
|
|
|
OnStageRankings.Broadcast(StageKey, Rankings);
|
2025-07-11 23:45:23 +02:00
|
|
|
|
ProcessStageRanking(Rankings);
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("ContestRanking added for Stage %i of Contest %i"),
|
|
|
|
|
|
Rankings.StageId, Rankings.ContestId);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("Unable to parse StageRanking"));
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
case EDTFluxApiDataType::SplitRanking:
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxSplitRankings Rankings;
|
|
|
|
|
|
if (InResponse.ParseSplitRanking(Rankings))
|
|
|
|
|
|
{
|
2025-07-12 09:41:15 +02:00
|
|
|
|
FDTFluxSplitKey SplitKey(Rankings.ContestId, Rankings.StageId, Rankings.SplitId);
|
|
|
|
|
|
OnSplitRankings.Broadcast(SplitKey, Rankings);
|
2025-07-11 23:45:23 +02:00
|
|
|
|
ProcessSplitRanking(Rankings);
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning,
|
|
|
|
|
|
TEXT("ContestRanking added for Split %i of Stage %i of Contest %i"),
|
|
|
|
|
|
Rankings.SplitId, Rankings.StageId, Rankings.ContestId);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("Unable to parse SplitRanking"));
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
case EDTFluxApiDataType::RaceData:
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxRaceData RaceData;
|
|
|
|
|
|
if (InResponse.ParseRaceData(RaceData))
|
|
|
|
|
|
{
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("RaceDataDefinition added for Contest %s"),
|
|
|
|
|
|
*RaceData.Datas[0].Name);
|
|
|
|
|
|
ProcessRaceData(RaceData);
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
case EDTFluxApiDataType::TeamList:
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxTeamListDefinition TeamList;
|
|
|
|
|
|
if (InResponse.ParseTeamList(TeamList))
|
|
|
|
|
|
{
|
|
|
|
|
|
ProcessTeamList(TeamList);
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Log, TEXT("Process TeamList"))
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
default:
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Unknown DataType %s"),
|
|
|
|
|
|
*UEnum::GetValueAsString(InResponse.GetResponseType()));
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-29 19:04:36 +02:00
|
|
|
|
void UDTFluxCoreSubsystem::RegisterDelegates()
|
|
|
|
|
|
{
|
2025-07-08 16:50:31 +02:00
|
|
|
|
if (NetworkSubsystem)
|
2025-06-29 19:04:36 +02:00
|
|
|
|
{
|
2025-07-08 16:50:31 +02:00
|
|
|
|
// ✅ Binding avec vérification automatique des signatures
|
|
|
|
|
|
// Si la signature ne correspond pas, erreur de compilation !
|
|
|
|
|
|
|
|
|
|
|
|
NetworkSubsystem->OnReceivedRaceData().BindUObject(
|
|
|
|
|
|
this,
|
|
|
|
|
|
&UDTFluxCoreSubsystem::ProcessRaceData
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
NetworkSubsystem->OnReceivedTeamList().BindUObject(
|
|
|
|
|
|
this,
|
|
|
|
|
|
&UDTFluxCoreSubsystem::ProcessTeamList
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
NetworkSubsystem->OnReceivedContestRanking().BindUObject(
|
|
|
|
|
|
this,
|
|
|
|
|
|
&UDTFluxCoreSubsystem::ProcessContestRanking
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
NetworkSubsystem->OnReceivedStageRanking().BindUObject(
|
|
|
|
|
|
this,
|
|
|
|
|
|
&UDTFluxCoreSubsystem::ProcessStageRanking
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
NetworkSubsystem->OnReceivedSplitRanking().BindUObject(
|
|
|
|
|
|
this,
|
|
|
|
|
|
&UDTFluxCoreSubsystem::ProcessSplitRanking
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
NetworkSubsystem->OnReceivedTeamStatusUpdate().BindUObject(
|
|
|
|
|
|
this,
|
|
|
|
|
|
&UDTFluxCoreSubsystem::ProcessTeamStatusUpdate
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
NetworkSubsystem->OnReceivedTeamUpdate().BindUObject(
|
|
|
|
|
|
this,
|
|
|
|
|
|
&UDTFluxCoreSubsystem::ProcessTeamUpdate
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
NetworkSubsystem->OnReceivedSplitSensor().BindUObject(
|
|
|
|
|
|
this,
|
|
|
|
|
|
&UDTFluxCoreSubsystem::ProcessSplitSensor
|
|
|
|
|
|
);
|
2025-06-29 19:04:36 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-14 15:40:03 +02:00
|
|
|
|
bool UDTFluxCoreSubsystem::IsStageRankingSealed(FDTFluxStageKey StageKey)
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxStageRankings StageRankings;
|
|
|
|
|
|
if (GetStageRankingsWithKey(StageKey, StageRankings))
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxStage Stage;
|
|
|
|
|
|
if (GetStageDefinition(StageKey, Stage))
|
|
|
|
|
|
{
|
|
|
|
|
|
return StageRankings.IsSealed(Stage.EndTime);
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("Unable to find Stage %i"), StageKey.StageId);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("Unable to find StageRankings for StageKey %i"), StageKey.StageId);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool UDTFluxCoreSubsystem::IsContestRankingSealed(int ContestId)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (DataStorage)
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxContestRankings ContestRankings;
|
|
|
|
|
|
if (GetContestRankings(ContestId, ContestRankings))
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxContest Contest;
|
|
|
|
|
|
if (GetContestForId(ContestId, Contest))
|
|
|
|
|
|
{
|
|
|
|
|
|
return ContestRankings.IsSealed(Contest.EndTime);
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("Unable to find Contest %i"), ContestId);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("Unable to find ContestRankings for ContestId %i"), ContestId);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DataStorage not available"));
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-07-03 17:28:51 +02:00
|
|
|
|
void UDTFluxCoreSubsystem::ProcessRaceData(const FDTFluxRaceData& RaceDataDefinition)
|
2025-06-29 19:04:36 +02:00
|
|
|
|
{
|
2025-07-08 16:50:31 +02:00
|
|
|
|
if (RaceDataDefinition.Datas.Num() > 0)
|
2025-06-29 19:04:36 +02:00
|
|
|
|
{
|
2025-07-08 16:50:31 +02:00
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Receiving RaceDataDefinition [%s]"),
|
|
|
|
|
|
*RaceDataDefinition.Datas[0].Name);
|
|
|
|
|
|
if (DataStorage != nullptr)
|
2025-06-29 19:04:36 +02:00
|
|
|
|
{
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DataStorage Name %s"), *DataStorage->EventName);
|
2025-07-08 16:50:31 +02:00
|
|
|
|
for (auto Contest : RaceDataDefinition.Datas)
|
2025-06-29 19:04:36 +02:00
|
|
|
|
{
|
|
|
|
|
|
DataStorage->AddContest(Contest);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DataStorage is null"));
|
|
|
|
|
|
}
|
2025-07-03 17:28:51 +02:00
|
|
|
|
SaveDataStorage();
|
2025-06-29 19:04:36 +02:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("RaceDataDefinition is empty !!!"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-03 17:28:51 +02:00
|
|
|
|
void UDTFluxCoreSubsystem::ProcessTeamList(const FDTFluxTeamListDefinition& TeamListDefinition)
|
2025-06-29 19:04:36 +02:00
|
|
|
|
{
|
2025-07-08 16:50:31 +02:00
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Received TeamList with %i Items"),
|
|
|
|
|
|
TeamListDefinition.Participants.Num());
|
|
|
|
|
|
for (const auto& Participant : TeamListDefinition.Participants)
|
2025-06-29 19:04:36 +02:00
|
|
|
|
{
|
2025-07-03 17:28:51 +02:00
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Add Participant %i in %i ContestId"),
|
2025-07-08 16:50:31 +02:00
|
|
|
|
Participant.Bib, Participant.ContestId);
|
2025-07-03 17:28:51 +02:00
|
|
|
|
|
|
|
|
|
|
DataStorage->AddParticipant(Participant, Participant.ContestId);
|
2025-06-29 19:04:36 +02:00
|
|
|
|
}
|
2025-07-08 16:50:31 +02:00
|
|
|
|
SaveDataStorage();
|
2025-06-29 19:04:36 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-03 17:28:51 +02:00
|
|
|
|
void UDTFluxCoreSubsystem::ProcessContestRanking(const FDTFluxContestRankings& ContestRankings)
|
2025-06-30 19:02:19 +02:00
|
|
|
|
{
|
2025-07-08 16:50:31 +02:00
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Received ContestRankings with %i Items"),
|
|
|
|
|
|
ContestRankings.Rankings.Num());
|
2025-06-30 19:02:19 +02:00
|
|
|
|
FDTFluxContestRankings NewContestRankings = ContestRankings;
|
2025-07-08 16:50:31 +02:00
|
|
|
|
NewContestRankings.SetName(DataStorage->GetContestNameForId(ContestRankings.ContestId));
|
2025-06-30 19:02:19 +02:00
|
|
|
|
DataStorage->AddContestRanking(NewContestRankings);
|
2025-07-08 16:50:31 +02:00
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("ContestRankings added for Contest %s"),
|
|
|
|
|
|
*NewContestRankings.ContestName);
|
2025-07-11 23:45:23 +02:00
|
|
|
|
if (bShouldKeepRankings)
|
|
|
|
|
|
{
|
|
|
|
|
|
SaveDataStorage();
|
|
|
|
|
|
}
|
2025-06-30 19:02:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-03 17:28:51 +02:00
|
|
|
|
void UDTFluxCoreSubsystem::ProcessStageRanking(const FDTFluxStageRankings& StageRankings)
|
2025-06-30 19:02:19 +02:00
|
|
|
|
{
|
2025-07-03 17:28:51 +02:00
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Received StageRankings with %i Items"), StageRankings.Rankings.Num());
|
|
|
|
|
|
DataStorage->UpdateOrCreateStageRanking(StageRankings);
|
2025-07-11 23:45:23 +02:00
|
|
|
|
if (bShouldKeepRankings) { SaveDataStorage(); }
|
2025-07-03 17:28:51 +02:00
|
|
|
|
}
|
2025-07-08 16:50:31 +02:00
|
|
|
|
|
2025-07-03 17:28:51 +02:00
|
|
|
|
void UDTFluxCoreSubsystem::ProcessSplitRanking(const FDTFluxSplitRankings& SplitRankings)
|
|
|
|
|
|
{
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Received SplitRanking with %i Items"), SplitRankings.Rankings.Num());
|
|
|
|
|
|
DataStorage->UpdateOrCreateSplitRanking(SplitRankings);
|
2025-07-11 23:45:23 +02:00
|
|
|
|
if (bShouldKeepRankings) { SaveDataStorage(); }
|
2025-07-04 01:13:07 +02:00
|
|
|
|
}
|
2025-07-03 17:28:51 +02:00
|
|
|
|
|
2025-07-04 01:13:07 +02:00
|
|
|
|
void UDTFluxCoreSubsystem::ProcessTeamStatusUpdate(const FDTFluxTeamStatusUpdate& NewParticipantStatus)
|
|
|
|
|
|
{
|
|
|
|
|
|
DataStorage->UpdateParticipantStatus(NewParticipantStatus);
|
2025-07-03 17:28:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-08 16:50:31 +02:00
|
|
|
|
void UDTFluxCoreSubsystem::ProcessTeamUpdate(const FDTFluxTeamListDefinition& TeamListDefinitiont)
|
2025-07-03 17:28:51 +02:00
|
|
|
|
{
|
2025-07-08 16:50:31 +02:00
|
|
|
|
for (const auto& Participant : TeamListDefinitiont.Participants)
|
|
|
|
|
|
{
|
|
|
|
|
|
DataStorage->UpdateParticipant(Participant);
|
|
|
|
|
|
}
|
2025-06-30 19:02:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-04 01:13:07 +02:00
|
|
|
|
void UDTFluxCoreSubsystem::ProcessSplitSensor(const FDTFluxSplitSensorInfo& SplitSensorInfo)
|
2025-06-29 19:04:36 +02:00
|
|
|
|
{
|
2025-07-04 01:13:07 +02:00
|
|
|
|
FDTFluxContest Contest;
|
|
|
|
|
|
FDTFluxStageKey StageKey(SplitSensorInfo.ContestId, SplitSensorInfo.StageId);
|
2025-07-08 16:50:31 +02:00
|
|
|
|
FDTFluxStage Stage;
|
|
|
|
|
|
DataStorage->GetStage(StageKey, Stage);
|
|
|
|
|
|
FDTFluxParticipant Participant;
|
|
|
|
|
|
DataStorage->GetParticipantByBib(SplitSensorInfo.Bib, Participant);
|
|
|
|
|
|
|
2025-07-04 01:13:07 +02:00
|
|
|
|
DataStorage->GetContestById(SplitSensorInfo.ContestId, Contest);
|
2025-07-08 16:50:31 +02:00
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Log, TEXT("%s|%s Split %i Sensor for Participant [Bib] %i [FullName] %s"),
|
|
|
|
|
|
*Contest.Name, *Stage.Name,
|
|
|
|
|
|
SplitSensorInfo.SplitId, SplitSensorInfo.Bib, *Participant.GetFormattedName());
|
2025-06-29 19:04:36 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void UDTFluxCoreSubsystem::SendRequest(const FString& Message)
|
|
|
|
|
|
{
|
2025-07-08 16:50:31 +02:00
|
|
|
|
if (NetworkSubsystem)
|
2025-06-29 19:04:36 +02:00
|
|
|
|
{
|
|
|
|
|
|
NetworkSubsystem->SendMessage(Message);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-14 15:40:03 +02:00
|
|
|
|
FGuid UDTFluxCoreSubsystem::InitContestRankingsDisplay(const int ContestId)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (NetworkSubsystem)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (DataStorage)
|
|
|
|
|
|
{
|
|
|
|
|
|
// no need to request StageRankings;
|
|
|
|
|
|
if (IsContestRankingSealed(ContestId))
|
|
|
|
|
|
{
|
|
|
|
|
|
const FGuid DisplayRequestId = FGuid::NewGuid();
|
|
|
|
|
|
OnContestRankingDisplayReady.Broadcast(DisplayRequestId, true);
|
|
|
|
|
|
return DisplayRequestId;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
FOnDTFluxRequestSuccess OnSuccess = FOnDTFluxRequestSuccess::CreateLambda(
|
|
|
|
|
|
[this](const FDTFluxTrackedRequest& Request)
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxContestRankings Rankings = FDTFluxContestRankings();
|
|
|
|
|
|
if (Request.ParsedResponse.IsSet())
|
|
|
|
|
|
{
|
|
|
|
|
|
TSharedPtr<FDTFluxServerResponse> ResponsePtr = Request.ParsedResponse.GetValue();
|
|
|
|
|
|
ResponsePtr->ParseContestRanking(Rankings);
|
|
|
|
|
|
this->DataStorage->AddContestRanking(Rankings);
|
|
|
|
|
|
this->OnContestRankingDisplayReady.Broadcast(Request.RequestId, true);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
this->OnStageRankingDisplayReady.Broadcast(Request.RequestId, false);
|
|
|
|
|
|
});
|
|
|
|
|
|
FOnDTFluxRequestError OnError = FOnDTFluxRequestError::CreateLambda(
|
|
|
|
|
|
[this](const FDTFluxTrackedRequest& InReq, const FString& InError)
|
|
|
|
|
|
{
|
|
|
|
|
|
this->OnStageRankingDisplayReady.Broadcast(InReq.RequestId, false);
|
|
|
|
|
|
});
|
|
|
|
|
|
FGuid DisplayRequestId = NetworkSubsystem->SendTrackedRequestWithCallbacks(
|
|
|
|
|
|
EDTFluxApiDataType::ContestRanking, ContestId, -1, -1, OnSuccess, OnError, true);
|
|
|
|
|
|
return DisplayRequestId;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DTFluxDatastorage unavailable ..."));
|
|
|
|
|
|
OnContestRankingDisplayReady.Broadcast(FGuid(), false);
|
|
|
|
|
|
return FGuid();
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DTFluxNetworkSubsystem unavailable ..."));
|
|
|
|
|
|
OnContestRankingDisplayReady.Broadcast(FGuid(), false);
|
|
|
|
|
|
return FGuid();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FGuid UDTFluxCoreSubsystem::InitStageRankingsDisplay(const int ContestId, const int StageId)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (NetworkSubsystem)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (DataStorage)
|
|
|
|
|
|
{
|
|
|
|
|
|
// no need to request StageRankings;
|
|
|
|
|
|
if (IsStageRankingSealed(FDTFluxStageKey(ContestId, StageId)))
|
|
|
|
|
|
{
|
|
|
|
|
|
const FGuid DisplayRequestId = FGuid::NewGuid();
|
|
|
|
|
|
OnStageRankingDisplayReady.Broadcast(DisplayRequestId, true);
|
|
|
|
|
|
return DisplayRequestId;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
FOnDTFluxRequestSuccess OnSuccess = FOnDTFluxRequestSuccess::CreateLambda(
|
|
|
|
|
|
[this](const FDTFluxTrackedRequest& Request)
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxStageRankings Rankings = FDTFluxStageRankings();
|
|
|
|
|
|
if (Request.ParsedResponse.IsSet())
|
|
|
|
|
|
{
|
|
|
|
|
|
TSharedPtr<FDTFluxServerResponse> ResponsePtr = Request.ParsedResponse.GetValue();
|
|
|
|
|
|
ResponsePtr->ParseStageRanking(Rankings);
|
|
|
|
|
|
this->DataStorage->AddStageRanking(Rankings);
|
|
|
|
|
|
this->OnStageRankingDisplayReady.Broadcast(Request.RequestId, true);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
this->OnStageRankingDisplayReady.Broadcast(Request.RequestId, false);
|
|
|
|
|
|
});
|
|
|
|
|
|
FOnDTFluxRequestError OnError = FOnDTFluxRequestError::CreateLambda(
|
|
|
|
|
|
[this](const FDTFluxTrackedRequest& InReq, const FString& InError)
|
|
|
|
|
|
{
|
|
|
|
|
|
this->OnStageRankingDisplayReady.Broadcast(InReq.RequestId, false);
|
|
|
|
|
|
});
|
|
|
|
|
|
FGuid DisplayRequestId = NetworkSubsystem->SendTrackedRequestWithCallbacks(
|
|
|
|
|
|
EDTFluxApiDataType::StageRanking, ContestId, StageId, -1, OnSuccess, OnError, true);
|
|
|
|
|
|
return DisplayRequestId;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DTFluxNetworkSubsystem unavailable ..."));
|
|
|
|
|
|
const FGuid RequestId = FGuid::NewGuid();
|
|
|
|
|
|
OnStageRankingDisplayReady.Broadcast(RequestId, false);
|
|
|
|
|
|
return RequestId;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FGuid UDTFluxCoreSubsystem::InitSplitRankingsDisplay(const int ContestId, const int StageId, const int SplitId)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (NetworkSubsystem)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (DataStorage)
|
|
|
|
|
|
{
|
|
|
|
|
|
FOnDTFluxRequestSuccess OnSuccess = FOnDTFluxRequestSuccess::CreateLambda(
|
|
|
|
|
|
[this](const FDTFluxTrackedRequest& Request)
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxSplitRankings Rankings = FDTFluxSplitRankings();
|
|
|
|
|
|
if (Request.ParsedResponse.IsSet())
|
|
|
|
|
|
{
|
|
|
|
|
|
TSharedPtr<FDTFluxServerResponse> ResponsePtr = Request.ParsedResponse.GetValue();
|
|
|
|
|
|
ResponsePtr->ParseSplitRanking(Rankings);
|
|
|
|
|
|
this->DataStorage->AddSplitRanking(Rankings);
|
|
|
|
|
|
this->OnSplitRankingDisplayReady.Broadcast(Request.RequestId, true);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
this->OnSplitRankingDisplayReady.Broadcast(Request.RequestId, false);
|
|
|
|
|
|
});
|
|
|
|
|
|
FOnDTFluxRequestError OnError = FOnDTFluxRequestError::CreateLambda(
|
|
|
|
|
|
[this](const FDTFluxTrackedRequest& InReq, const FString& InError)
|
|
|
|
|
|
{
|
|
|
|
|
|
this->OnSplitRankingDisplayReady.Broadcast(InReq.RequestId, false);
|
|
|
|
|
|
});
|
|
|
|
|
|
FGuid DisplayRequestId = NetworkSubsystem->SendTrackedRequestWithCallbacks(
|
2025-07-15 04:59:59 +02:00
|
|
|
|
EDTFluxApiDataType::SplitRanking, ContestId, StageId, SplitId, OnSuccess, OnError, true);
|
2025-07-14 15:40:03 +02:00
|
|
|
|
return DisplayRequestId;
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DTFluxDatastorage unavailable ..."));
|
|
|
|
|
|
OnSplitRankingDisplayReady.Broadcast(FGuid(), false);
|
|
|
|
|
|
return FGuid();
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DTFluxNetworkSubsystem unavailable ..."));
|
|
|
|
|
|
OnSplitRankingDisplayReady.Broadcast(FGuid(), false);
|
|
|
|
|
|
return FGuid();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-14 02:40:03 +02:00
|
|
|
|
bool UDTFluxCoreSubsystem::GetStageRankingForBib(const int ContestId, const int StageId, const int Bib,
|
|
|
|
|
|
FDTFluxStageRanking& OutStageRanking)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (DataStorage)
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxStageKey StageKey(ContestId, StageId);
|
|
|
|
|
|
if (DataStorage->StageRankings.Contains(StageKey))
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxStageRankings StageRankings = DataStorage->StageRankings[StageKey];
|
|
|
|
|
|
for (auto& Ranking : StageRankings.Rankings)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Ranking.Bib == Bib)
|
|
|
|
|
|
{
|
|
|
|
|
|
OutStageRanking = static_cast<FDTFluxStageRanking>(Ranking);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Unable to find StageRanking for Bib %i"), Bib);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DataStorage not available"));
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool UDTFluxCoreSubsystem::GetSplitRankingForBib(const int ContestId, const int StageId, const int SplitId,
|
|
|
|
|
|
const int Bib, FDTFluxSplitRanking& OutSplitRankings)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (DataStorage)
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxSplitKey SplitKey(ContestId, StageId, SplitId);
|
|
|
|
|
|
if (DataStorage->SplitRankings.Contains(SplitKey))
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxSplitRankings SplitRankings = DataStorage->SplitRankings[SplitKey];
|
|
|
|
|
|
for (auto& Ranking : SplitRankings.Rankings)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Ranking.Bib == Bib)
|
|
|
|
|
|
{
|
|
|
|
|
|
OutSplitRankings = static_cast<FDTFluxSplitRanking>(Ranking);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Unable to find SplitRanking for Bib %i"), Bib);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DataStorage not available"));
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool UDTFluxCoreSubsystem::GetContestRanking(const int ContestId, FDTFluxContestRanking& OutContestRanking)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (DataStorage)
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxContest Contest;
|
|
|
|
|
|
if (GetContestForId(ContestId, Contest))
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto& Ranking : DataStorage->ContestRankings[ContestId].Rankings)
|
|
|
|
|
|
{
|
|
|
|
|
|
OutContestRanking = Ranking;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Unable to find ContestRanking for ContestId %i"), ContestId);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DataStorage not available"));
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-11 19:04:37 +02:00
|
|
|
|
bool UDTFluxCoreSubsystem::GetContestRankings(const int ContestId,
|
|
|
|
|
|
FDTFluxContestRankings& OutContestRankings)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (DataStorage->ContestRankings.Contains(ContestId))
|
|
|
|
|
|
{
|
|
|
|
|
|
OutContestRankings = DataStorage->ContestRankings[ContestId];
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (NetworkSubsystem)
|
|
|
|
|
|
{
|
|
|
|
|
|
TArray<int> TackedContestIds = {ContestId};
|
|
|
|
|
|
TrackedRequestContestRankings(TackedContestIds);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("NetworkSubsystem unavailable"));
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool UDTFluxCoreSubsystem::GetStageRankings(const int ContestId, const int StageId,
|
|
|
|
|
|
FDTFluxStageRankings& OutStageRankings)
|
|
|
|
|
|
{
|
|
|
|
|
|
return GetStageRankingsWithKey(FDTFluxStageKey(ContestId, StageId), OutStageRankings);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool UDTFluxCoreSubsystem::GetSplitRankings(const int ContestId, const int StageId, const int SplitId,
|
|
|
|
|
|
FDTFluxSplitRankings& OutSplitRankings)
|
|
|
|
|
|
{
|
|
|
|
|
|
return GetSplitRankingsWithKey(FDTFluxSplitKey(ContestId, StageId, SplitId), OutSplitRankings);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool UDTFluxCoreSubsystem::GetStageRankingsWithKey(const FDTFluxStageKey StageKey,
|
|
|
|
|
|
FDTFluxStageRankings& OutStageRankings, const bool bShouldUseCached)
|
|
|
|
|
|
{
|
|
|
|
|
|
//We Have the data
|
|
|
|
|
|
if (DataStorage->StageRankings.Contains(StageKey) && bShouldUseCached)
|
|
|
|
|
|
{
|
|
|
|
|
|
OutStageRankings = DataStorage->StageRankings[StageKey];
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (NetworkSubsystem)
|
|
|
|
|
|
{
|
|
|
|
|
|
TArray<FDTFluxStageKey> TackedStageKeys = {StageKey};
|
|
|
|
|
|
TrackedRequestStageRankings(TackedStageKeys);
|
|
|
|
|
|
OutStageRankings = FDTFluxStageRankings();
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("NetworkSubsystem unavailable"))
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool UDTFluxCoreSubsystem::GetSplitRankingsWithKey(const FDTFluxSplitKey SplitKey,
|
|
|
|
|
|
FDTFluxSplitRankings& OutSplitRankings, const bool bShouldUseCached)
|
|
|
|
|
|
{
|
|
|
|
|
|
//We Have the data
|
|
|
|
|
|
if (DataStorage->SplitRankings.Contains(SplitKey) && bShouldUseCached)
|
|
|
|
|
|
{
|
|
|
|
|
|
OutSplitRankings = DataStorage->SplitRankings[SplitKey];
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (NetworkSubsystem)
|
|
|
|
|
|
{
|
|
|
|
|
|
TArray<FDTFluxSplitKey> TackedSplitKey = {SplitKey};
|
|
|
|
|
|
TrackedRequestSplitRankings(TackedSplitKey);
|
|
|
|
|
|
OutSplitRankings = FDTFluxSplitRankings();
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("NetworkSubsystem unavailable"))
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-12 16:07:37 +02:00
|
|
|
|
TArray<FGuid> UDTFluxCoreSubsystem::TrackedRequestContestRankings(const TArray<int> ForContests, bool bEnableCache)
|
2025-07-11 19:04:37 +02:00
|
|
|
|
{
|
|
|
|
|
|
if (NetworkSubsystem)
|
|
|
|
|
|
{
|
|
|
|
|
|
TArray<FGuid> RequestIds;
|
|
|
|
|
|
FOnDTFluxRequestSuccess OnSuccess = FOnDTFluxRequestSuccess::CreateLambda(
|
|
|
|
|
|
[this](const FDTFluxTrackedRequest& Request)
|
|
|
|
|
|
{
|
2025-07-11 23:45:23 +02:00
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Log, TEXT("ContestRanking Request %s %s Success"),
|
2025-07-11 19:04:37 +02:00
|
|
|
|
*Request.RequestId.ToString(), *UEnum::GetValueAsString(Request.RequestType));
|
2025-07-11 23:45:23 +02:00
|
|
|
|
if (Request.ParsedResponse.IsSet())
|
|
|
|
|
|
{
|
|
|
|
|
|
ProcessTrackedResponse(*Request.ParsedResponse.GetValue());
|
|
|
|
|
|
}
|
2025-07-11 19:04:37 +02:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
FOnDTFluxRequestError OnError = FOnDTFluxRequestError::CreateLambda(
|
|
|
|
|
|
[this](const FDTFluxTrackedRequest& InReq, const FString& InError)
|
|
|
|
|
|
{
|
2025-07-11 23:45:23 +02:00
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Log, TEXT("ContestRanking Request [%s] Error %s"),
|
2025-07-11 19:04:37 +02:00
|
|
|
|
*InReq.RequestId.ToString(), *InError);
|
|
|
|
|
|
});
|
|
|
|
|
|
// if Contest is not ended
|
|
|
|
|
|
for (auto ContestId : ForContests)
|
|
|
|
|
|
{
|
|
|
|
|
|
FGuid ContestRequest = NetworkSubsystem->SendTrackedRequestWithCallbacks(EDTFluxApiDataType::ContestRanking,
|
2025-07-12 16:07:37 +02:00
|
|
|
|
ContestId, -1, -1, OnSuccess, OnError, bEnableCache);
|
2025-07-11 19:04:37 +02:00
|
|
|
|
RequestIds.Add(ContestRequest);
|
|
|
|
|
|
}
|
|
|
|
|
|
return RequestIds;
|
|
|
|
|
|
}
|
|
|
|
|
|
return TArray<FGuid>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-12 16:07:37 +02:00
|
|
|
|
TArray<FGuid> UDTFluxCoreSubsystem::TrackedRequestStageRankings(const TArray<FDTFluxStageKey> ForStages,
|
|
|
|
|
|
bool bEnableCache)
|
2025-07-11 19:04:37 +02:00
|
|
|
|
{
|
|
|
|
|
|
if (NetworkSubsystem)
|
|
|
|
|
|
{
|
|
|
|
|
|
TArray<FGuid> RequestIds;
|
|
|
|
|
|
FOnDTFluxRequestSuccess OnSuccess = FOnDTFluxRequestSuccess::CreateLambda(
|
|
|
|
|
|
[this](const FDTFluxTrackedRequest& Request)
|
|
|
|
|
|
{
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Stage Request %s %s Success"),
|
|
|
|
|
|
*Request.RequestId.ToString(), *UEnum::GetValueAsString(Request.RequestType));
|
2025-07-11 23:45:23 +02:00
|
|
|
|
if (Request.ParsedResponse.IsSet())
|
|
|
|
|
|
{
|
|
|
|
|
|
ProcessTrackedResponse(*Request.ParsedResponse.GetValue());
|
|
|
|
|
|
}
|
2025-07-11 19:04:37 +02:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
FOnDTFluxRequestError OnError = FOnDTFluxRequestError::CreateLambda(
|
|
|
|
|
|
[this](const FDTFluxTrackedRequest& InReq, const FString& InError)
|
|
|
|
|
|
{
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("StageRanking Request [%s] Error %s"),
|
|
|
|
|
|
*InReq.RequestId.ToString(), *InError);
|
|
|
|
|
|
});
|
|
|
|
|
|
for (auto StageKey : ForStages)
|
|
|
|
|
|
{
|
|
|
|
|
|
FGuid ContestRequest = NetworkSubsystem->SendTrackedRequestWithCallbacks(EDTFluxApiDataType::StageRanking,
|
2025-07-12 16:07:37 +02:00
|
|
|
|
StageKey.ContestId, StageKey.StageId, -1, OnSuccess, OnError, bEnableCache);
|
2025-07-11 19:04:37 +02:00
|
|
|
|
RequestIds.Add(ContestRequest);
|
|
|
|
|
|
}
|
|
|
|
|
|
return RequestIds;
|
|
|
|
|
|
}
|
|
|
|
|
|
return TArray<FGuid>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-12 16:07:37 +02:00
|
|
|
|
TArray<FGuid> UDTFluxCoreSubsystem::TrackedRequestSplitRankings(const TArray<FDTFluxSplitKey> ForSplits,
|
|
|
|
|
|
bool bEnableCache)
|
2025-07-11 19:04:37 +02:00
|
|
|
|
{
|
|
|
|
|
|
if (NetworkSubsystem)
|
|
|
|
|
|
{
|
|
|
|
|
|
TArray<FGuid> RequestIds;
|
|
|
|
|
|
FOnDTFluxRequestSuccess OnSuccess = FOnDTFluxRequestSuccess::CreateLambda(
|
|
|
|
|
|
[this](const FDTFluxTrackedRequest& Request)
|
|
|
|
|
|
{
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Stage Request %s %s Success"),
|
|
|
|
|
|
*Request.RequestId.ToString(), *UEnum::GetValueAsString(Request.RequestType));
|
2025-07-11 23:45:23 +02:00
|
|
|
|
if (Request.ParsedResponse.IsSet())
|
|
|
|
|
|
{
|
|
|
|
|
|
ProcessTrackedResponse(*Request.ParsedResponse.GetValue());
|
|
|
|
|
|
}
|
2025-07-11 19:04:37 +02:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
FOnDTFluxRequestError OnError = FOnDTFluxRequestError::CreateLambda(
|
|
|
|
|
|
[this](const FDTFluxTrackedRequest& InReq, const FString& InError)
|
|
|
|
|
|
{
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("StageRanking Request [%s] Error %s"),
|
|
|
|
|
|
*InReq.RequestId.ToString(), *InError);
|
|
|
|
|
|
});
|
|
|
|
|
|
// if Contest is not ended
|
|
|
|
|
|
for (auto SplitKey : ForSplits)
|
|
|
|
|
|
{
|
|
|
|
|
|
FGuid ContestRequest = NetworkSubsystem->SendTrackedRequestWithCallbacks(EDTFluxApiDataType::SplitRanking,
|
2025-07-12 16:07:37 +02:00
|
|
|
|
SplitKey.ContestId, SplitKey.StageId, SplitKey.SplitId, OnSuccess, OnError, bEnableCache);
|
2025-07-11 19:04:37 +02:00
|
|
|
|
RequestIds.Add(ContestRequest);
|
|
|
|
|
|
}
|
|
|
|
|
|
return RequestIds;
|
|
|
|
|
|
}
|
|
|
|
|
|
return TArray<FGuid>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-14 02:40:03 +02:00
|
|
|
|
bool UDTFluxCoreSubsystem::GetParticipant(int InBib, FDTFluxParticipant& OutParticipant)
|
2025-07-08 20:16:36 +02:00
|
|
|
|
{
|
|
|
|
|
|
if (DataStorage->Participants.Contains(InBib))
|
|
|
|
|
|
{
|
2025-07-14 02:40:03 +02:00
|
|
|
|
OutParticipant = DataStorage->Participants[InBib];
|
|
|
|
|
|
return true;
|
2025-07-08 20:16:36 +02:00
|
|
|
|
}
|
2025-07-14 02:40:03 +02:00
|
|
|
|
|
|
|
|
|
|
return false;
|
2025-07-08 20:16:36 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-04 15:17:22 +02:00
|
|
|
|
TArray<int> UDTFluxCoreSubsystem::GetCurrentContestsId()
|
|
|
|
|
|
{
|
|
|
|
|
|
return GetContestsIdForTime(FDateTime::Now());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-14 09:58:10 +02:00
|
|
|
|
bool UDTFluxCoreSubsystem::GetCurrentContests(TArray<FDTFluxContest>& OutContests)
|
2025-07-04 15:17:22 +02:00
|
|
|
|
{
|
2025-07-14 09:58:10 +02:00
|
|
|
|
return GetContestsForTime(FDateTime::Now(), OutContests);
|
2025-07-04 15:17:22 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-14 09:58:10 +02:00
|
|
|
|
TArray<int> UDTFluxCoreSubsystem::GetContestsIdForTime(const FDateTime Time)
|
2025-07-04 15:17:22 +02:00
|
|
|
|
{
|
2025-07-14 09:58:10 +02:00
|
|
|
|
if (DataStorage)
|
2025-07-04 15:17:22 +02:00
|
|
|
|
{
|
2025-07-14 09:58:10 +02:00
|
|
|
|
TArray<FDTFluxContest> Contests;
|
|
|
|
|
|
if (GetContestsForTime(Time, Contests))
|
2025-07-04 15:17:22 +02:00
|
|
|
|
{
|
2025-07-14 09:58:10 +02:00
|
|
|
|
TArray<int> ContestIds = TArray<int>();
|
|
|
|
|
|
for (const auto& Contest : Contests)
|
|
|
|
|
|
{
|
|
|
|
|
|
ContestIds.Add(Contest.ContestId);
|
|
|
|
|
|
}
|
|
|
|
|
|
return ContestIds;
|
2025-07-04 15:17:22 +02:00
|
|
|
|
}
|
2025-07-14 09:58:10 +02:00
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("No Contest running for Time [%s]"), *Time.ToString());
|
|
|
|
|
|
return TArray<int>();
|
2025-07-04 15:17:22 +02:00
|
|
|
|
}
|
2025-07-14 09:58:10 +02:00
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DataStorage not available"));
|
|
|
|
|
|
return TArray<int>();
|
2025-07-04 15:17:22 +02:00
|
|
|
|
}
|
2025-07-08 16:50:31 +02:00
|
|
|
|
|
2025-07-08 20:16:36 +02:00
|
|
|
|
bool UDTFluxCoreSubsystem::GetContestForId(const int Id, FDTFluxContest& OutContest)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto KeyPair : DataStorage->Contests)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (KeyPair.Value.ContestId == Id)
|
|
|
|
|
|
{
|
|
|
|
|
|
OutContest = KeyPair.Value;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Cannot find Contest for Id [%i]"), Id);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-14 09:58:10 +02:00
|
|
|
|
bool UDTFluxCoreSubsystem::GetContestsForTime(const FDateTime Time, TArray<FDTFluxContest>& OutContests)
|
2025-07-04 15:17:22 +02:00
|
|
|
|
{
|
2025-07-14 09:58:10 +02:00
|
|
|
|
if (DataStorage)
|
2025-07-04 15:17:22 +02:00
|
|
|
|
{
|
2025-07-14 09:58:10 +02:00
|
|
|
|
OutContests.Empty();
|
|
|
|
|
|
for (const auto& Pair : DataStorage->Contests)
|
|
|
|
|
|
{
|
|
|
|
|
|
FDTFluxContest Contest = Pair.Value;
|
|
|
|
|
|
int ContestId = Contest.ContestId;
|
|
|
|
|
|
|
|
|
|
|
|
//ils ont commencé.
|
|
|
|
|
|
if (Contest.Date < Time && Contest.EndTime > Time)
|
|
|
|
|
|
{
|
|
|
|
|
|
// ils sont finis
|
|
|
|
|
|
if (!Contest.IsFinished())
|
|
|
|
|
|
{
|
|
|
|
|
|
OutContests.Add(Contest);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!OutContests.IsEmpty())
|
2025-07-04 15:17:22 +02:00
|
|
|
|
{
|
2025-07-14 09:58:10 +02:00
|
|
|
|
return true;
|
2025-07-04 15:17:22 +02:00
|
|
|
|
}
|
2025-07-14 09:58:10 +02:00
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("No Contest running for Time [%s]"), *Time.ToString());
|
2025-07-04 15:17:22 +02:00
|
|
|
|
}
|
2025-07-14 09:58:10 +02:00
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DataStorage not available"));
|
|
|
|
|
|
return false;
|
2025-07-08 16:50:31 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-14 09:58:10 +02:00
|
|
|
|
bool UDTFluxCoreSubsystem::GetContests(TArray<FDTFluxContest>& OutContests)
|
2025-07-08 16:50:31 +02:00
|
|
|
|
{
|
2025-07-14 09:58:10 +02:00
|
|
|
|
OutContests.Empty();
|
2025-07-08 16:50:31 +02:00
|
|
|
|
if (DataStorage)
|
|
|
|
|
|
{
|
|
|
|
|
|
DataStorage->Contests.GenerateValueArray(OutContests);
|
2025-07-14 09:58:10 +02:00
|
|
|
|
return !OutContests.IsEmpty();
|
2025-07-08 16:50:31 +02:00
|
|
|
|
}
|
2025-07-14 09:58:10 +02:00
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DataStorage not available"));
|
|
|
|
|
|
return false;
|
2025-07-08 16:50:31 +02:00
|
|
|
|
}
|
2025-07-14 09:33:25 +02:00
|
|
|
|
|
|
|
|
|
|
void UDTFluxCoreSubsystem::GetContest(const int ContestId, FDTFluxContest& OutContest)
|
|
|
|
|
|
{
|
|
|
|
|
|
OutContest = FDTFluxContest();
|
|
|
|
|
|
if (GetContestForId(ContestId, OutContest))
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("ContestId %d not found in ContestDefinition"), ContestId)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool UDTFluxCoreSubsystem::GetStageDefinition(const FDTFluxStageKey StageKey, FDTFluxStage& OutStageDefinition)
|
|
|
|
|
|
{
|
|
|
|
|
|
int ContestId = StageKey.ContestId;
|
|
|
|
|
|
int StageId = StageKey.StageId;
|
|
|
|
|
|
FDTFluxContest ContestDefinition;
|
|
|
|
|
|
if (GetContestForId(ContestId, ContestDefinition))
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto& Stage : ContestDefinition.Stages)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Stage.StageId == StageId)
|
|
|
|
|
|
{
|
|
|
|
|
|
OutStageDefinition = Stage;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
OutStageDefinition = FDTFluxStage();
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("ContestId %d, StageId %d not found in ContestDefinition"),
|
|
|
|
|
|
ContestId, StageId)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool UDTFluxCoreSubsystem::GetSplitDefinition(const FDTFluxSplitKey SplitKey, FDTFluxSplit& OutSplitDefinition)
|
|
|
|
|
|
{
|
|
|
|
|
|
int ContestId = SplitKey.ContestId;
|
|
|
|
|
|
int SplitId = SplitKey.SplitId;
|
|
|
|
|
|
FDTFluxContest ContestDefinition;
|
|
|
|
|
|
if (GetContestForId(ContestId, ContestDefinition))
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto& Split : ContestDefinition.Splits)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Split.SplitId == SplitId)
|
|
|
|
|
|
{
|
|
|
|
|
|
OutSplitDefinition = Split;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
OutSplitDefinition = FDTFluxSplit();
|
|
|
|
|
|
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("ContestId %d, SplitId %d not found in ContestDefinition"),
|
|
|
|
|
|
ContestId, SplitId);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void UDTFluxCoreSubsystem::GetStage(const int ContestId, const int StageId, FDTFluxStage& OutStageDefinition)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (GetStageDefinition(FDTFluxStageKey(ContestId, StageId),
|
|
|
|
|
|
OutStageDefinition))
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
OutStageDefinition = FDTFluxStage();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void UDTFluxCoreSubsystem::GetSplit(const int ContestId, const int StageId, const int SplitId,
|
|
|
|
|
|
FDTFluxSplit& OutSplitDefinition)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (GetSplitDefinition(FDTFluxSplitKey(ContestId, StageId, SplitId),
|
|
|
|
|
|
OutSplitDefinition))
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
OutSplitDefinition = FDTFluxSplit();
|
|
|
|
|
|
}
|