// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "UObject/Object.h" #include "DTFluxNetworkModule.h" #include "DTFluxRaceDataServerResponse.h" #include "DTFluxRankingServerResponse.h" #include "DTFluxSplitSensorServerResponse.h" #include "JsonObjectConverter.h" #include "Types/Enum/DTFluxCoreEnum.h" #include "Types/Objects/UDTFluxParticipantFactory.h" #include "Types/Struct/DTFluxRaceDataStructs.h" #include "Types/Struct/DTFluxRankingStructs.h" #include "Types/Struct/DTFluxSplitSensor.h" #include "DTFluxServerResponseStruct.generated.h" /** * Enum pour indiquer le statut du parsing */ UENUM(BlueprintType) enum class EDTFluxResponseStatus : uint8 { Unset = 0b00000000 UMETA(DisplayName="Unset"), Success = 0b10000000 UMETA(DisplayName="Success"), JsonParseError = 0b00000001 UMETA(DisplayName="JsonParseError"), ServerError = 0b00000010 UMETA(DisplayName="ServerError"), InvalidType = 0b00000100 UMETA(DisplayName="InvalidType"), MissingData = 0b00001000 UMETA(DisplayName="MissingData"), DataError = 0b00010000 UMETA(DisplayName="MissingData"), UnknownError = 0b00100000 UMETA(DisplayName="UnknownError") }; /** * Struct representing a mixed root json server response with integrated parsing capabilities */ USTRUCT() struct DTFLUXNETWORK_API FDTFluxServerResponse { GENERATED_BODY() public: UPROPERTY() FString Type = ""; UPROPERTY() int Code = -1; UPROPERTY() FString Message = ""; UPROPERTY() FString Trigger = ""; UPROPERTY() int ContestID = -1; UPROPERTY() int StageID = -1; UPROPERTY() int SplitID = -1; UPROPERTY() FDateTime ReceivedAt; UPROPERTY() FString RawMessage; UPROPERTY() FName RequestId = FName(""); UPROPERTY() FText FailureReason; // === CONSTRUCTEURS === FDTFluxServerResponse(); FDTFluxServerResponse(const FString& JsonMessage, EDTFluxResponseStatus& OutStatus, bool bLogErrors = true); static FDTFluxServerResponse CreateFromJson(const FString& JsonMessage, bool bLogErrors = true); // === MÉTHODES DE PARSING === EDTFluxResponseStatus TryParse(bool bLogErrors = true); bool ParseTeamListResponse(FDTFluxTeamListDefinition& OutTeamList); bool ParseTeamUpdateResponse(FDTFluxTeamListDefinition& OutTeamUpdate); bool ParseRaceData(FDTFluxRaceData& OutRaceData); bool ParseContestRanking(FDTFluxContestRankings& OutContestRankings); bool ParseStageRankingResponse(FDTFluxStageRankings& OutStageRankings); bool ParseSplitRankingResponse(FDTFluxSplitRankings& OutSplitRankings); bool ParseStatusUpdateResponse(FDTFluxTeamStatusUpdate& OutStatusUpdate); bool ParseSplitSensorResponse(TArray& OutSplitSensorInfos); // === MÉTHODES UTILITAIRES === bool IsValidResponse() const { return Code == -1; } bool IsSuccessfullyParsed() const { return ParsingStatus == EDTFluxResponseStatus::Success; } EDTFluxResponseStatus GetParsingStatus() const { return ParsingStatus; } EDTFluxApiDataType GetResponseType() const { return ApiDataType; } FString GetDataType() const { return Type; } bool ContainsDataType(const FString& DataType) const { return Type.Contains(DataType); } FString ToDebugString() const; void ShowDebug(const bool bShouldPrintRawMessage = false) const; FString GetErrorMessage() const; private: // === DONNÉES INTERNES === EDTFluxApiDataType ApiDataType; // Statut du parsing initial EDTFluxResponseStatus ParsingStatus = EDTFluxResponseStatus::Unset; // === MÉTHODES PRIVÉES DE PARSING === bool ParseJsonObject(TSharedPtr& OutJsonObject) const; bool ValidateResponseType(const FString& ExpectedType) const; EDTFluxResponseStatus InitializeFromJson(const FString& JsonMessage, bool bLogErrors); static FString GetJsonType(const EJson Type) { switch (Type) { case EJson::None: return TEXT("None"); case EJson::Null: return TEXT("Null"); case EJson::String: return TEXT("String"); case EJson::Number: return TEXT("Number"); case EJson::Boolean: return TEXT("Boolean"); case EJson::Array: return TEXT("Array"); case EJson::Object: return TEXT("Object"); default: return TEXT("Unknown"); } } };