First Commit with code
This commit is contained in:
3
Config/DefaultDTFluxAPI.ini
Normal file
3
Config/DefaultDTFluxAPI.ini
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[CoreRedirects]
|
||||||
|
+ClassRedirects=(OldName="/Script/DTFluxAPI.DTHttpServerObject",NewName="/Script/DTFluxAPI.DTFluxHttpServerObject")
|
||||||
|
+StructRedirects=(OldName="/Script/DTFluxAPI.DTHttpServerParams",NewName="/Script/DTFluxAPI.DTFluxHttpServerParams")
|
||||||
30
DTFluxAPI.uplugin
Normal file
30
DTFluxAPI.uplugin
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"FileVersion": 3,
|
||||||
|
"Version": 1,
|
||||||
|
"VersionName": "1.0",
|
||||||
|
"FriendlyName": "DTFluxAPI",
|
||||||
|
"Description": "DTFlux API plugin",
|
||||||
|
"Category": "Other",
|
||||||
|
"CreatedBy": "Ange-Marie MAURIN",
|
||||||
|
"CreatedByURL": "",
|
||||||
|
"DocsURL": "",
|
||||||
|
"MarketplaceURL": "",
|
||||||
|
"SupportURL": "",
|
||||||
|
"CanContainContent": true,
|
||||||
|
"IsBetaVersion": false,
|
||||||
|
"IsExperimentalVersion": false,
|
||||||
|
"Installed": false,
|
||||||
|
"Modules": [
|
||||||
|
{
|
||||||
|
"Name": "DTFluxAPI",
|
||||||
|
"Type": "Runtime",
|
||||||
|
"LoadingPhase": "Default"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Plugins": [
|
||||||
|
{
|
||||||
|
"Name": "Avalanche",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
Resources/Icon128.png
Normal file
BIN
Resources/Icon128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
36
Source/DTFluxAPI/DTFluxAPI.Build.cs
Normal file
36
Source/DTFluxAPI/DTFluxAPI.Build.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
using UnrealBuildTool;
|
||||||
|
|
||||||
|
public class DTFluxAPI : ModuleRules
|
||||||
|
{
|
||||||
|
public DTFluxAPI(ReadOnlyTargetRules Target) : base(Target)
|
||||||
|
{
|
||||||
|
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||||
|
|
||||||
|
PublicDependencyModuleNames.AddRange(
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
"Core"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
PrivateDependencyModuleNames.AddRange(
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
"CoreUObject",
|
||||||
|
"Engine",
|
||||||
|
"Slate",
|
||||||
|
"SlateCore",
|
||||||
|
"HTTPServer",
|
||||||
|
"HTTP",
|
||||||
|
"DeveloperToolSettings",
|
||||||
|
"DeveloperSettings",
|
||||||
|
"Json",
|
||||||
|
"JsonUtilities",
|
||||||
|
"AvalancheCore",
|
||||||
|
"AvalancheMedia",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
22
Source/DTFluxAPI/Private/DTFluxAPI.cpp
Normal file
22
Source/DTFluxAPI/Private/DTFluxAPI.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
#include "DTFluxAPI.h"
|
||||||
|
#include "DTFluxAPILog.h"
|
||||||
|
|
||||||
|
#define LOCTEXT_NAMESPACE "FDTFluxAPIModule"
|
||||||
|
DEFINE_LOG_CATEGORY(LogDTFluxAPI);
|
||||||
|
|
||||||
|
void FDTFluxAPIModule::StartupModule()
|
||||||
|
{
|
||||||
|
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDTFluxAPIModule::ShutdownModule()
|
||||||
|
{
|
||||||
|
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
|
||||||
|
// we call this function before unloading the module.
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef LOCTEXT_NAMESPACE
|
||||||
|
|
||||||
|
IMPLEMENT_MODULE(FDTFluxAPIModule, DTFluxAPI)
|
||||||
4
Source/DTFluxAPI/Private/DTFluxModel/DTFluxModel.cpp
Normal file
4
Source/DTFluxAPI/Private/DTFluxModel/DTFluxModel.cpp
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "DTFluxModel/DTFluxModel.h"
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "DTFluxProjectSettings/DTFluxProjectSettings.h"
|
||||||
|
|
||||||
|
FString UDTFluxProjectSettings::GetAPIPath(const TEnumAsByte<EDTFluxAPIRoute> RouteType, const FString& Filters) const
|
||||||
|
{
|
||||||
|
FString ApiAccessRoute;
|
||||||
|
UE_LOG(LogDTFluxAPI, Type::Log, TEXT("Filters in GetApiPath settings\nGot %s"), *Filters);
|
||||||
|
|
||||||
|
if (bAccessIsLocal)
|
||||||
|
{
|
||||||
|
// http://localhost/_246158/api/8O8JMI2739JS58R8KRJGJEZUSQXF807O
|
||||||
|
ApiAccessRoute += RaceResultPort != 80 ? FString::Printf(TEXT("%s:%i/_%s/api/"), *ProxyUrl, RaceResultPort, *APIToken) :
|
||||||
|
FString::Printf(TEXT("%s/_%s/api/"), *ProxyUrl, *APIToken);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// https://api.raceresult.com/246158/8O8JMI2739JS58R8KRJGJEZUSQXF807O
|
||||||
|
ApiAccessRoute += FString::Printf(TEXT("https://api.raceresult.com/%s/"), *APIToken);
|
||||||
|
}
|
||||||
|
switch(RouteType)
|
||||||
|
{
|
||||||
|
case (EDTFluxAPIRoute::Results):
|
||||||
|
return ApiAccessRoute + LiveStageResultsAccessToken + Filters;
|
||||||
|
break;
|
||||||
|
case (EDTFluxAPIRoute::FinalClassification):
|
||||||
|
return ApiAccessRoute + GeneralClassificationAccessToken + Filters;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return ApiAccessRoute + StartListAccessToken + Filters;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FString UDTFluxProjectSettings::GetAPIPathFiltered(const TEnumAsByte<EDTFluxAPIRoute> RouteType,
|
||||||
|
const FSearchFilters& Filters) const
|
||||||
|
{
|
||||||
|
const FString Filter = Filters.GetFilter();
|
||||||
|
UE_LOG(LogDTFluxAPI, Type::Log, TEXT("Filters in Project settings\nGot %s"), *Filter);
|
||||||
|
return GetAPIPath(RouteType, Filter );
|
||||||
|
}
|
||||||
|
|
||||||
|
FString UDTFluxProjectSettings::GetProxyPath(const TEnumAsByte<EDTFluxProxyRoute> RouteType,
|
||||||
|
const int& InContest, const int& InStage ) const
|
||||||
|
{
|
||||||
|
switch(RouteType)
|
||||||
|
{
|
||||||
|
case (EDTFluxProxyRoute::ProxyRankingContest):
|
||||||
|
return FString::Printf(TEXT("%s:%i%s/ranking/contest/%i/"), *ProxyAddress, ProxyPort, *ProxyRootPath, InContest);
|
||||||
|
break;
|
||||||
|
case (EDTFluxProxyRoute::ProxyRankingStage):
|
||||||
|
return FString::Printf(TEXT("%s:%i%s/ranking/contest/%i/stage?id=%i"),
|
||||||
|
*ProxyAddress, ProxyPort, *ProxyRootPath, InContest, InStage);
|
||||||
|
break;
|
||||||
|
case (EDTFluxProxyRoute::ProxyTeams):
|
||||||
|
return FString::Printf(TEXT("%s:%i%s/teams/"), *ProxyAddress, ProxyPort, *ProxyRootPath);
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
return FString::Printf(TEXT("%s:%i%s/race/datas/"), *ProxyAddress, ProxyPort, *ProxyRootPath);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const UDTFluxProjectSettings* UDTFluxProjectSettings::GetDTFluxAPIProjectSettings()
|
||||||
|
{
|
||||||
|
return GetDefault<UDTFluxProjectSettings>();
|
||||||
|
}
|
||||||
|
|
||||||
|
UDTFluxProjectSettings::UDTFluxProjectSettings()
|
||||||
|
{
|
||||||
|
SectionName = "DTFlux Settings";
|
||||||
|
}
|
||||||
331
Source/DTFluxAPI/Private/DTFluxSubsystem/DTFluxSubsystem.cpp
Normal file
331
Source/DTFluxAPI/Private/DTFluxSubsystem/DTFluxSubsystem.cpp
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#include "DTFluxSubsystem/DTFluxSubsystem.h"
|
||||||
|
#include "DTFluxProjectSettings/DTFluxProjectSettings.h"
|
||||||
|
#include "DTFluxModel/DTFluxModel.h"
|
||||||
|
#include "HttpServerModule.h"
|
||||||
|
#include "HttpRouteHandle.h"
|
||||||
|
#include "DTFluxAPILog.h"
|
||||||
|
#include "IHttpRouter.h"
|
||||||
|
#include "HttpModule.h"
|
||||||
|
#include "JsonObjectConverter.h"
|
||||||
|
#include "Interfaces/IHttpResponse.h"
|
||||||
|
|
||||||
|
// TODO: Not implemented
|
||||||
|
bool UDTFluxSubsystem::OnRequest(const FHttpServerRequest& Request)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// TODO: Not implemented
|
||||||
|
void UDTFluxSubsystem::HandleRequest(const FString& Route,const FHttpServerRequest& Request, FHttpResultCallback OnComplete)
|
||||||
|
{
|
||||||
|
// creating payload string
|
||||||
|
FString ReqPayload;
|
||||||
|
if (Request.Body.Num() > 0)
|
||||||
|
{
|
||||||
|
const std::string RawBody((char*)Request.Body.GetData(), Request.Body.Num());
|
||||||
|
ReqPayload = UTF8_TO_TCHAR(RawBody.c_str());
|
||||||
|
}
|
||||||
|
TSharedPtr<FJsonObject> JsonPayload;
|
||||||
|
if(!FJsonSerializer::Deserialize(TJsonReaderFactory<>::Create(ReqPayload), JsonPayload))
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Error, TEXT("unable to parse JSON Payload\n%s"), *ReqPayload);
|
||||||
|
}
|
||||||
|
//Checking path
|
||||||
|
|
||||||
|
UE_LOG(LogDTFluxAPI,Log, TEXT("Request Received for Route %s"), *Route);
|
||||||
|
|
||||||
|
// EventStart
|
||||||
|
if(Route == TEXT("/event/start"))
|
||||||
|
{
|
||||||
|
FDTFluxStartStagePayload StartStagePayload;
|
||||||
|
FJsonObjectConverter::JsonObjectToUStruct<FDTFluxStartStagePayload>(JsonPayload.ToSharedRef(), &StartStagePayload, 0, 0);
|
||||||
|
OnEventStartReceived.Broadcast(StartStagePayload);
|
||||||
|
}
|
||||||
|
else if(Route == TEXT("/team/create"))
|
||||||
|
{
|
||||||
|
// /team/create route
|
||||||
|
}
|
||||||
|
else if(Route == TEXT("/team/update"))
|
||||||
|
{
|
||||||
|
// /team/create route
|
||||||
|
} else if(Route == TEXT("/team/create"))
|
||||||
|
{
|
||||||
|
// /team/create route
|
||||||
|
}
|
||||||
|
// Default Route
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Preparing Response Header
|
||||||
|
TUniquePtr<FHttpServerResponse> Response = CreateHttpServerResponse();
|
||||||
|
|
||||||
|
// Adding Response Body
|
||||||
|
FDTFluxResponseBody RespBody;
|
||||||
|
RespBody.Success = TEXT("OK");
|
||||||
|
std::string RespBody_c;
|
||||||
|
RespBody_c = TCHAR_TO_UTF8(*RespBody.Deserialize());
|
||||||
|
Response->Body.Append((const uint8*)RespBody_c.c_str(), RespBody_c.length());
|
||||||
|
// Return the response
|
||||||
|
OnComplete(MoveTemp(Response));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxSubsystem::OnUpdateStartList(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
|
||||||
|
{
|
||||||
|
if (!bWasSuccessful || !Response.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Error, TEXT("RaceResult Request failed"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Tricks because Payload root is an array
|
||||||
|
const FString ModifiedData = FString::Printf(TEXT("{\"Participants\":%s}"), *Response->GetContentAsString());
|
||||||
|
TSharedPtr<FJsonObject> Payload;
|
||||||
|
if(!FJsonSerializer::Deserialize(TJsonReaderFactory<>::Create(ModifiedData), Payload))
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Error, TEXT("unable to parse JSON Payload****"));
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
FDTFluxStartListPayload StartList;
|
||||||
|
if (FJsonObjectConverter::JsonObjectToUStruct<FDTFluxStartListPayload>(Payload.ToSharedRef(), &StartList, 0, 0))
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Log, TEXT("Success Reading"))
|
||||||
|
|
||||||
|
for(const auto& Participant : StartList.Participants)
|
||||||
|
{
|
||||||
|
// Creating a new Contest
|
||||||
|
if(!Contests.Contests.Contains(Participant.ContestName))
|
||||||
|
{
|
||||||
|
FDTFluxContest NewContest;
|
||||||
|
NewContest.ContestID = Participant.ContestID;
|
||||||
|
NewContest.ContestName = Participant.ContestName;
|
||||||
|
Contests.Contests.Add(Participant.ContestName, NewContest);
|
||||||
|
}
|
||||||
|
FDTFluxContest* CurrentContest = Contests.Contests.Find(Participant.ContestName);
|
||||||
|
|
||||||
|
FDTFluxTeam Team;
|
||||||
|
Team.Bib = Participant.Bib;
|
||||||
|
FDTFluxParticipant ContestParticipant;
|
||||||
|
ContestParticipant.FirstName = Participant.FirstName;
|
||||||
|
ContestParticipant.LastName = Participant.LastName;
|
||||||
|
ContestParticipant.Gender = Participant.Gender;
|
||||||
|
ContestParticipant.Club = Participant.Club;
|
||||||
|
ContestParticipant.Category = Participant.Category;
|
||||||
|
|
||||||
|
Team.Participants.Add(ContestParticipant);
|
||||||
|
// if we have LastName2 it is a two personne Team
|
||||||
|
if(Participant.LastName2 != "")
|
||||||
|
{
|
||||||
|
FDTFluxParticipant ContestParticipant2;
|
||||||
|
ContestParticipant2.FirstName = Participant.FirstName2;
|
||||||
|
ContestParticipant2.LastName = Participant.LastName2;
|
||||||
|
ContestParticipant2.Gender = Participant.Gender2;
|
||||||
|
ContestParticipant2.Club = Participant.Club2;
|
||||||
|
ContestParticipant2.Category = Participant.Category;
|
||||||
|
Team.Participants.Add(ContestParticipant);
|
||||||
|
Team.TeamName = Participant.TeamName;
|
||||||
|
UE_LOG(LogDTFluxAPI, Log, TEXT("Participant is a team : TeamName \"%s\" "), *Team.TeamName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Team.TeamName = Participant.FirstName + TEXT(" ") + Participant.LastName.ToUpper();
|
||||||
|
}
|
||||||
|
// check if Participant already exists
|
||||||
|
|
||||||
|
if(!CurrentContest->TeamAlreadyExist(Team))
|
||||||
|
{
|
||||||
|
// Add it to the TeamList
|
||||||
|
CurrentContest->AddTeam(Team);
|
||||||
|
UE_LOG(LogDTFluxAPI, Log, TEXT("Adding Team \"%s\" "), *Team.TeamName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
UE_LOG(LogDTFluxAPI, Log, TEXT("Contest has now %i elements"), Contests.Contests.Num());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Error, TEXT("Error Deserializing Payload \n*%s*\n"), *ModifiedData);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(const auto& Element : Contests.Contests)
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Log, TEXT("Contest %s"), *Element.Key);
|
||||||
|
FDTFluxContest Contest = Element.Value;
|
||||||
|
UE_LOG(LogDTFluxAPI, Log, TEXT("Number of participants in this contest %i"), Contest.TeamParticipants.Num());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TUniquePtr<FHttpServerResponse> UDTFluxSubsystem::CreateHttpServerResponse() const
|
||||||
|
{
|
||||||
|
// Create a Response to be returned by the server
|
||||||
|
TUniquePtr<FHttpServerResponse> Response = MakeUnique<FHttpServerResponse>();
|
||||||
|
Response->Code = EHttpServerResponseCodes::Ok;
|
||||||
|
// Response Header
|
||||||
|
Response->Headers.Add(TEXT("Content-Type"), { TEXT("application/json;charset=utf-8") });
|
||||||
|
Response->Headers.Add(TEXT("Access-Control-Allow-Origin"), { TEXT("*") });
|
||||||
|
Response->Headers.Add(TEXT("Access-Control-Allow-Methods"), { TEXT("GET,POST,PUT,PATCH,DELETE,OPTIONS") });
|
||||||
|
Response->Headers.Add(TEXT("Access-Control-Allow-Headers"), { TEXT("Origin,X-Requested-With,Content-Type,Accept") });
|
||||||
|
Response->Headers.Add(TEXT("Access-Control-Max-Age"), { TEXT("600") });
|
||||||
|
Response->Headers.Add(TEXT("Access-Control-Allow-Credentials"), { TEXT("true") });
|
||||||
|
Response->Headers.Add(TEXT("Server"), { TEXT("UE 5.4.1 EMBBEDED") });
|
||||||
|
|
||||||
|
return Response;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
||||||
|
{
|
||||||
|
Super::Initialize(Collection);
|
||||||
|
mSettings = UDTFluxProjectSettings::GetDTFluxAPIProjectSettings();
|
||||||
|
if(mSettings)
|
||||||
|
{
|
||||||
|
// Setting up request
|
||||||
|
HttpRequest = &FHttpModule::Get();
|
||||||
|
HttpRouter = FHttpServerModule::Get().GetHttpRouter(mSettings->InPort);
|
||||||
|
if(!HttpRouter)
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Type::Error, TEXT("Invalid Http Router for port : %i"), mSettings->InPort)
|
||||||
|
}
|
||||||
|
// Setting Up Routes
|
||||||
|
for(const TArray<FString> Routes = mSettings->Endpoints; const FString& Route : Routes)
|
||||||
|
{
|
||||||
|
const FHttpRequestHandler OptionRequestHandler = FHttpRequestHandler::CreateLambda([this](const FHttpServerRequest &Request, const FHttpResultCallback& OnComplete)
|
||||||
|
{
|
||||||
|
OnComplete(CreateHttpServerResponse());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
FHttpRouteHandle OptionRouteHandle = HttpRouter->BindRoute(Route, EHttpServerRequestVerbs::VERB_OPTIONS, OptionRequestHandler);
|
||||||
|
HttpMountedMap.Add(Route + TEXT("HTTPOption"), OptionRouteHandle);
|
||||||
|
|
||||||
|
const FHttpRequestHandler RequestHandler = FHttpRequestHandler::CreateLambda([this, Route](const FHttpServerRequest& Request, const FHttpResultCallback& OnComplete)
|
||||||
|
{
|
||||||
|
// Processing Request to Raw OnRequestReceived firing
|
||||||
|
FDTFluxHttpServerHeaders Headers;
|
||||||
|
for(const auto &Header: Request.Headers)
|
||||||
|
{
|
||||||
|
Headers.Headers.Add(Header.Key, FString::Join(Header.Value, TEXT(",")));
|
||||||
|
}
|
||||||
|
FDTFluxHttpServerParams Params;
|
||||||
|
Params.Params = Request.QueryParams;
|
||||||
|
|
||||||
|
FDTFluxHttpServerBody Payload;
|
||||||
|
Payload.ReqBody = Request.Body;
|
||||||
|
|
||||||
|
// Raw broadcasting Received event
|
||||||
|
OnRequestReceived.Broadcast(Headers, Params, Payload);
|
||||||
|
HandleRequest(Route, Request, OnComplete);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
// Binding Routes
|
||||||
|
FHttpRouteHandle RouteHandle = HttpRouter->BindRoute(Route, EHttpServerRequestVerbs::VERB_POST, RequestHandler);
|
||||||
|
HttpMountedMap.Add(Route, RouteHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxSubsystem::Deinitialize()
|
||||||
|
{
|
||||||
|
StopServer();
|
||||||
|
UE_LOG(LogDTFluxAPI, Log, TEXT("Route Num %i"), HttpMountedMap.Num());
|
||||||
|
for( auto const& Route: HttpMountedMap)
|
||||||
|
{
|
||||||
|
HttpRouter->UnbindRoute(Route.Value);
|
||||||
|
}
|
||||||
|
HttpMountedMap.Empty();
|
||||||
|
HttpRouter.Reset();
|
||||||
|
Super::Deinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
TArray<FString> UDTFluxSubsystem::GetMountedRoutes() const
|
||||||
|
{
|
||||||
|
TArray<FString> Mounted = TArray<FString>();
|
||||||
|
for(const auto Route : HttpMountedMap)
|
||||||
|
{
|
||||||
|
Mounted.Add(Route.Key);
|
||||||
|
}
|
||||||
|
return Mounted;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxSubsystem::StartServer()
|
||||||
|
{
|
||||||
|
if(bIsListening){return ;}
|
||||||
|
FHttpServerModule::Get().StartAllListeners();
|
||||||
|
bIsListening = true;
|
||||||
|
OnServerListening.Broadcast();
|
||||||
|
}
|
||||||
|
|
||||||
|
TArray<FDTFluxTeam> UDTFluxSubsystem::GetParticipantsByContestId(const int ContestId)
|
||||||
|
{
|
||||||
|
if(Contests.Contests.Num() != 0)
|
||||||
|
{
|
||||||
|
FString ContestName = Contests.GetContestName(ContestId);
|
||||||
|
UE_LOG(LogDTFluxAPI, Log, TEXT("Getting Participants for Contest %s"), *ContestName);
|
||||||
|
return GetParticipantsByContestName(ContestName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Error, TEXT("No Contest Yet !!!!"));
|
||||||
|
TArray<FDTFluxTeam> EmptyTeam;
|
||||||
|
return EmptyTeam;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TArray<FDTFluxTeam> UDTFluxSubsystem::GetParticipantsByContestName(const FString ContestName)
|
||||||
|
{
|
||||||
|
if(Contests.Contests.Num() != 0)
|
||||||
|
{
|
||||||
|
return Contests.Contests[ContestName].TeamParticipants;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Error, TEXT("No Contest Yet !!!!"));
|
||||||
|
TArray<FDTFluxTeam> EmptyTeam;
|
||||||
|
return EmptyTeam;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FString UDTFluxSubsystem::GetContestName(const int ContestId)
|
||||||
|
{
|
||||||
|
if(Contests.GetContestName(ContestId) != "")
|
||||||
|
{
|
||||||
|
return Contests.GetContestName(ContestId);
|
||||||
|
}
|
||||||
|
return TEXT("");
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxSubsystem::UpdateStartList()
|
||||||
|
{
|
||||||
|
const TSharedRef<IHttpRequest> Req = HttpRequest->CreateRequest();
|
||||||
|
Req->SetVerb("GET");
|
||||||
|
Req->SetURL(mSettings->GetAPIPath(EDTFluxAPIRoute::Starters));
|
||||||
|
Req->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
|
||||||
|
Req->OnProcessRequestComplete().BindUObject(this, &UDTFluxSubsystem::OnUpdateStartList);
|
||||||
|
|
||||||
|
Req->ProcessRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxSubsystem::UpdateClassification(const int& ContestId, const int& StageId)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TArray<FDTFluxParticipant> UDTFluxSubsystem::GetClassification(const int& ContestId, const int& StageId)
|
||||||
|
{
|
||||||
|
return TArray<FDTFluxParticipant>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxSubsystem::StopServer()
|
||||||
|
{
|
||||||
|
FHttpServerModule::Get().StopAllListeners();
|
||||||
|
bIsListening = false;
|
||||||
|
OnServerStopped.Broadcast();
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2023 Dexter.Wan. All Rights Reserved.
|
||||||
|
// EMail: 45141961@qq.com
|
||||||
|
|
||||||
|
#include "DTFluxUtils/DTFluxHttpServerStruct.h"
|
||||||
|
|
||||||
|
void UDTFluxHttpServerBPFn::BreakParams(const FDTFluxHttpServerParams& HttpServerParams, TMap<FString, FString>& Params)
|
||||||
|
{
|
||||||
|
Params = HttpServerParams.Params;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxHttpServerBPFn::FindParam(const FDTFluxHttpServerParams& HttpServerParams, const FString& Key, FString& Param)
|
||||||
|
{
|
||||||
|
Param.Empty();
|
||||||
|
if ( const FString * pParam = HttpServerParams.Params.Find(Key) )
|
||||||
|
{
|
||||||
|
Param = *pParam;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxHttpServerBPFn::BreakHeaders(const FDTFluxHttpServerHeaders& HttpServerHeaders, TMap<FString, FString>& Headers)
|
||||||
|
{
|
||||||
|
Headers = HttpServerHeaders.Headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxHttpServerBPFn::BreakBody(const FDTFluxHttpServerBody& HttpBody, TArray<uint8> RawBody)
|
||||||
|
{
|
||||||
|
RawBody = HttpBody.ReqBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDTFluxHttpServerBPFn::FindHeader(const FDTFluxHttpServerHeaders& HttpServerHeaders, const FString& Key, FString& Header)
|
||||||
|
{
|
||||||
|
Header.Empty();
|
||||||
|
if ( const FString * pHeader = HttpServerHeaders.Headers.Find(Key) )
|
||||||
|
{
|
||||||
|
Header = *pHeader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
15
Source/DTFluxAPI/Public/DTFluxAPI.h
Normal file
15
Source/DTFluxAPI/Public/DTFluxAPI.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Modules/ModuleManager.h"
|
||||||
|
|
||||||
|
class FDTFluxAPIModule : public IModuleInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** IModuleInterface implementation */
|
||||||
|
virtual void StartupModule() override;
|
||||||
|
virtual void ShutdownModule() override;
|
||||||
|
};
|
||||||
6
Source/DTFluxAPI/Public/DTFluxAPILog.h
Normal file
6
Source/DTFluxAPI/Public/DTFluxAPILog.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
|
||||||
|
DECLARE_LOG_CATEGORY_EXTERN(LogDTFluxAPI, Log, All);
|
||||||
423
Source/DTFluxAPI/Public/DTFluxModel/DTFluxModel.h
Normal file
423
Source/DTFluxAPI/Public/DTFluxModel/DTFluxModel.h
Normal file
@ -0,0 +1,423 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "UObject/Object.h"
|
||||||
|
#include "DTFluxModel.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
struct FDTFluxTeam;
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct DTFLUXAPI_API FDTFLuxStartStageData
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Type;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Contest;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Stage;
|
||||||
|
|
||||||
|
// Maybe this one can be made DATETIME
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString RealStartTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct DTFLUXAPI_API FDTFluxStartStagePayload
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Description;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Trigger;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Type;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
TArray<FDTFLuxStartStageData> Datas;
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct DTFLUXAPI_API FDTFluxStartListItemPayload
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
// "Report": "Start List",
|
||||||
|
// "ContestID": 0,
|
||||||
|
// "ContestName": "",
|
||||||
|
// "Bib": 1039,
|
||||||
|
// "Firstname": "Mystère",
|
||||||
|
// "Lastname": "Mystère",
|
||||||
|
// "Gender": "",
|
||||||
|
// "Club": "",
|
||||||
|
// "Firstname2": "",
|
||||||
|
// "Lastname2": "",
|
||||||
|
// "Gender2": "",
|
||||||
|
// "Club2": "",
|
||||||
|
// "TeamName": "",
|
||||||
|
// "Category": "",
|
||||||
|
// "Elite": false
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
int ContestID;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString ContestName;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
int Bib;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString FirstName;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString LastName;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Gender;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Club;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString FirstName2;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString LastName2;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Gender2;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Club2;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString TeamName;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Category;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
bool Elite;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct DTFLUXAPI_API FDTFluxStartListPayload
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
TArray<FDTFluxStartListItemPayload> Participants;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct DTFLUXAPI_API FDTFluxParticipant
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString FirstName;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString LastName;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Club;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Gender;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Category;
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct DTFLUXAPI_API FDTFluxTeam
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
TArray<FDTFluxParticipant> Participants;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString TeamName;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
int Bib;
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct FDTFluxContest
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
int ContestID;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString ContestName;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
TArray<FDTFluxTeam> TeamParticipants;
|
||||||
|
|
||||||
|
bool AddTeam(FDTFluxTeam Team)
|
||||||
|
{
|
||||||
|
TeamParticipants.Add(Team);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool TeamAlreadyExist(FDTFluxTeam Team)
|
||||||
|
{
|
||||||
|
for(const auto& MyTeam : TeamParticipants)
|
||||||
|
{
|
||||||
|
// Compare Bib
|
||||||
|
if(MyTeam.Bib == Team.Bib )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct DTFLUXAPI_API FDTFluxContestList
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
TMap<FString, FDTFluxContest>Contests;
|
||||||
|
|
||||||
|
int GetContestId(const FString& ContestName) const
|
||||||
|
{
|
||||||
|
const FDTFluxContest* Contest = Contests.Find(ContestName);
|
||||||
|
if(Contest)
|
||||||
|
{
|
||||||
|
return Contest->ContestID;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
FString GetContestName(const int& ContestId) const
|
||||||
|
{
|
||||||
|
for (const auto& Contest : Contests)
|
||||||
|
{
|
||||||
|
if (Contest.Value.ContestID == ContestId)
|
||||||
|
{
|
||||||
|
return Contest.Key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UCLASS(Blueprintable, Category="DTFlux|Model")
|
||||||
|
class DTFLUXAPI_API UDTFluxContestBPFn : public UBlueprintFunctionLibrary
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
UFUNCTION(BlueprintPure, Category = "DT Http Server|Params")
|
||||||
|
static int GetContestId(const FDTFluxContestList& ContestList, const FString& ContestName)
|
||||||
|
{
|
||||||
|
return ContestList.GetContestId(ContestName);
|
||||||
|
}
|
||||||
|
UFUNCTION(BlueprintPure, Category = "DT Http Server|Params")
|
||||||
|
static FString GetContestName(const FDTFluxContestList& ContestList, const int& ContestId)
|
||||||
|
{
|
||||||
|
return ContestList.GetContestName(ContestId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// TeamListItem Response from proxy Containing Team definition
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct FResponseTeamListItem
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Contest;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
int Bib;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString FirstName;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString LastName;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Gender;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
bool Elite;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Club;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Team;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Category;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Status;
|
||||||
|
};
|
||||||
|
// TeamList Response from proxy Containing List of Team
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct FProxyResponseTeamList
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
TArray<FResponseTeamListItem> Datas;
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct FProxyResponseStageListItem
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
int Id;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Name;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString StartTime;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString EndTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct FProxyResponseSplitsListItem
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
int Id;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Name;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct FProxyResponseRaceListItem
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
int Id;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Name;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Date;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
TArray<FProxyResponseStageListItem> Stages;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
TArray<FProxyResponseSplitsListItem> Splits;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct FProxyResponseContestRankingListItem
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
int Bib;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
int Rank;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Time;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Gap;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct FProxyResponseContestRankingList
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
int ContestId;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
TArray<FProxyResponseContestRankingListItem> Datas;
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct FProxyResponseStageRankingListItem
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
int Bib;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
int Rank;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Time;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Gap;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString TimeSwim;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString TimeTransition;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString TimeRun;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString TimeStart;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||||
|
struct FProxyResponseStageRankingList
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
int ContestId;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
int StageId;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
TArray<FProxyResponseStageRankingListItem> Datas;
|
||||||
|
|
||||||
|
};
|
||||||
@ -0,0 +1,154 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Engine/DeveloperSettings.h"
|
||||||
|
#include "DTFluxAPILog.h"
|
||||||
|
#include "DTFluxProjectSettings.generated.h"
|
||||||
|
|
||||||
|
UENUM()
|
||||||
|
enum EDTFluxAPIRoute: uint8
|
||||||
|
{
|
||||||
|
Root UMETA(DisplayName="API Root"),
|
||||||
|
Results UMETA(DisplayName="Results Route"),
|
||||||
|
Starters UMETA(DisplayName="Starters List Route"),
|
||||||
|
FinalClassification UMETA(DisplayName="Final Classification Route"),
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UENUM()
|
||||||
|
enum EDTFluxProxyRoute : uint8
|
||||||
|
{
|
||||||
|
ProxyRaceData UMETA(DisplayName="Proxy Race Data"),
|
||||||
|
ProxyRankingContest UMETA(DisplayName="Proxy Ranking Contest Data"),
|
||||||
|
ProxyRankingStage UMETA(DisplayName="Proxy Ranking Stage Data"),
|
||||||
|
ProxyTeams UMETA(DisplayName="Proxy Teams Data"),
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType)
|
||||||
|
struct FSearchFilters
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Config", EditAnywhere)
|
||||||
|
int ContestId = 0;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Config", EditAnywhere)
|
||||||
|
int StageId = 0;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Config", EditAnywhere)
|
||||||
|
int GenderId = 0;
|
||||||
|
|
||||||
|
FString GetFilter() const
|
||||||
|
{
|
||||||
|
if(ContestId == 0 && StageId == 0 && GenderId == 0)
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Type::Log, TEXT("Gender Test -> %i"), GenderId);
|
||||||
|
return FString();
|
||||||
|
}
|
||||||
|
TArray<FString> Filters;
|
||||||
|
Filters.Add(FString("?"));
|
||||||
|
if (ContestId > 0)
|
||||||
|
{
|
||||||
|
Filters.Add(FString::Printf(TEXT("Contest=%i"), ContestId) );
|
||||||
|
}
|
||||||
|
if (StageId > 0)
|
||||||
|
{
|
||||||
|
Filters.Add(FString::Printf(TEXT("SelectorResult=%i"), StageId) );
|
||||||
|
}
|
||||||
|
if (GenderId > 0)
|
||||||
|
{
|
||||||
|
switch(GenderId)
|
||||||
|
{
|
||||||
|
case (2):
|
||||||
|
// default is male
|
||||||
|
UE_LOG(LogDTFluxAPI, Type::Log, TEXT("Gender Female -> %i"), GenderId);
|
||||||
|
|
||||||
|
Filters.Add(FString(TEXT("filter=[Gender]=\"f\"") ) );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// default is male
|
||||||
|
UE_LOG(LogDTFluxAPI, Type::Log, TEXT("Gender male -> %i"), GenderId);
|
||||||
|
Filters.Add(FString(TEXT("filter=[Gender]=\"m\"") ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(const auto& Element : Filters)
|
||||||
|
{
|
||||||
|
UE_LOG(LogDTFluxAPI, Type::Log, TEXT("Element : %s"), *Element);
|
||||||
|
|
||||||
|
}
|
||||||
|
FString FinalFilters = FString::Join(Filters, TEXT("&"));
|
||||||
|
FinalFilters.RemoveAt(1);
|
||||||
|
return FinalFilters;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
UCLASS(Blueprintable, Config=Engine, DefaultConfig, meta=(DisplayName="DTFlux Project Settings"))
|
||||||
|
class DTFLUXAPI_API UDTFluxProjectSettings : public UDeveloperSettings
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
UPROPERTY(Category="DTFlux|Server Config", Config, EditAnywhere, BlueprintReadOnly)
|
||||||
|
int InPort = 8080;
|
||||||
|
|
||||||
|
UPROPERTY(Category="DTFlux|Config|Race Result API", Config, EditAnywhere, BlueprintReadOnly)
|
||||||
|
int RaceResultPort = 80;
|
||||||
|
|
||||||
|
UPROPERTY(Category="DTFlux|Server Config", Config, EditAnywhere, BlueprintReadOnly)
|
||||||
|
TArray<FString> Endpoints;
|
||||||
|
|
||||||
|
UPROPERTY(Category="DTFlux|Config|Race Result API", Config, EditAnywhere, BlueprintReadOnly)
|
||||||
|
FString ProxyUrl = "http://localhost";
|
||||||
|
|
||||||
|
UPROPERTY(Category="DTFlux|Config|Race Result API", Config, EditAnywhere, BlueprintReadOnly)
|
||||||
|
FString APIToken;
|
||||||
|
|
||||||
|
UPROPERTY(Category="DTFlux|Config|Race Result API", Config, EditAnywhere, BlueprintReadOnly)
|
||||||
|
bool bAccessIsLocal = true;
|
||||||
|
|
||||||
|
UPROPERTY(Category="DTFlux|Config|Race Result API", Config, EditAnywhere, BlueprintReadOnly)
|
||||||
|
FString StartListAccessToken;
|
||||||
|
|
||||||
|
UPROPERTY(Category="DTFlux|Config|Race Result API", Config, EditAnywhere, BlueprintReadOnly)
|
||||||
|
FString GeneralClassificationAccessToken;
|
||||||
|
|
||||||
|
UPROPERTY(Category="DTFlux|Config|Race Result API", Config, EditAnywhere, BlueprintReadOnly)
|
||||||
|
FString LiveStageResultsAccessToken ;
|
||||||
|
|
||||||
|
UPROPERTY(Category="DTFlux|Config|Chrono Proxy", Config, EditAnywhere, BlueprintReadOnly)
|
||||||
|
FString ProxyAddress = "http://localhost";
|
||||||
|
|
||||||
|
UPROPERTY(Category="DTFlux|Config|Chrono Proxy", Config, EditAnywhere, BlueprintReadOnly)
|
||||||
|
FString ProxyRootPath = "/endpoints";
|
||||||
|
|
||||||
|
UPROPERTY(Category="DTFlux|Chrono Proxy", Config, EditAnywhere, BlueprintReadOnly)
|
||||||
|
int ProxyPort = 8000;
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Config")
|
||||||
|
FString GetAPIPath(const TEnumAsByte<EDTFluxAPIRoute> RouteType, const FString& Filters = TEXT("") ) const;
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Config")
|
||||||
|
FString GetAPIPathFiltered(const TEnumAsByte<EDTFluxAPIRoute> RouteType, const FSearchFilters& Filters ) const;
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Config")
|
||||||
|
FString GetProxyPath(const TEnumAsByte<EDTFluxProxyRoute> RouteType, const int& InContest = -1, const int& InStage = -1) const;
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Config")
|
||||||
|
static const UDTFluxProjectSettings* GetDTFluxAPIProjectSettings();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
UDTFluxProjectSettings();
|
||||||
|
};
|
||||||
|
|
||||||
153
Source/DTFluxAPI/Public/DTFluxSubsystem/DTFluxSubsystem.h
Normal file
153
Source/DTFluxAPI/Public/DTFluxSubsystem/DTFluxSubsystem.h
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Runtime/Engine/Public/Subsystems/EngineSubsystem.h"
|
||||||
|
#include "HttpServerRequest.h"
|
||||||
|
#include "HttpResultCallback.h"
|
||||||
|
#include "HttpRouteHandle.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "DTFluxUtils/DTFluxHttpServerStruct.h"
|
||||||
|
#include "DTFluxAPILog.h"
|
||||||
|
#include "DTFluxModel/DTFluxModel.h"
|
||||||
|
|
||||||
|
#include "DTFluxSubsystem.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
class UDTFluxProjectSettings;
|
||||||
|
class IHttpRouter;
|
||||||
|
|
||||||
|
class IHttpRequest;
|
||||||
|
class IHttpResponse;
|
||||||
|
|
||||||
|
class FHttpModule;
|
||||||
|
typedef TSharedPtr<IHttpRequest, ESPMode::ThreadSafe> FHttpRequestPtr;
|
||||||
|
typedef TSharedPtr<IHttpResponse, ESPMode::ThreadSafe> FHttpResponsePtr;
|
||||||
|
|
||||||
|
UENUM(BlueprintType, Category="DTFlux|Server")
|
||||||
|
enum EDTFluxResponseErrorCode
|
||||||
|
{
|
||||||
|
Unknown_Error UMETA(DisplayName="Unknown Error"),
|
||||||
|
InvalidBody_Error UMETA(DisplayName="Invalid Body"),
|
||||||
|
InvalidRequest_Error UMETA(DisplayName="Invalid Request"),
|
||||||
|
Internal_Error UMETA(DisplayName="Internal Server Error")
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Server")
|
||||||
|
struct FDTFluxResponseBody
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Error;
|
||||||
|
|
||||||
|
UPROPERTY(Blueprintable, Category="DTFlux|Model", BlueprintReadOnly)
|
||||||
|
FString Success;
|
||||||
|
|
||||||
|
FString Deserialize()
|
||||||
|
{
|
||||||
|
FString JSONObject;
|
||||||
|
JSONObject += TEXT("{");
|
||||||
|
JSONObject += TEXT("\"error\":\"");
|
||||||
|
JSONObject += Error.IsEmpty() ? TEXT("") : Error;
|
||||||
|
JSONObject += TEXT("\",\"success\":\"");
|
||||||
|
JSONObject += Success.IsEmpty() ? TEXT("") : Success;
|
||||||
|
JSONObject += TEXT("\"}");
|
||||||
|
UE_LOG(LogDTFluxAPI, Log, TEXT("JSONObject : %s"), *JSONObject);
|
||||||
|
return JSONObject;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FDTFluxOnRequestReceived, FDTFluxHttpServerHeaders, HttpServerHeaders,
|
||||||
|
FDTFluxHttpServerParams, HttpServerParams, FDTFluxHttpServerBody, HttpRequestBody);
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDTFluxOnServerListening);
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDTFluxOnServerStopped);
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDTFluxOnEventStartReceived, FDTFluxStartStagePayload, Payload);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DTFlux API Subsystem
|
||||||
|
*
|
||||||
|
* This Subsystem Mount HTTP routes to be listened and an HTTP poller to retrieve basic information.
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class DTFLUXAPI_API UDTFluxSubsystem : public UEngineSubsystem
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool bIsListening = false;
|
||||||
|
const UDTFluxProjectSettings* mSettings;
|
||||||
|
|
||||||
|
bool OnRequest(const FHttpServerRequest& Request);
|
||||||
|
|
||||||
|
void HandleRequest(const FString& Route, const FHttpServerRequest& Request, FHttpResultCallback OnComplete);
|
||||||
|
// // StartList Payload;
|
||||||
|
// FDTFluxStartListPayload StartList;
|
||||||
|
// Contest storage
|
||||||
|
FDTFluxContestList Contests;
|
||||||
|
|
||||||
|
void OnUpdateStartList(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
TMap<FString, FHttpRouteHandle> HttpMountedMap;
|
||||||
|
TSharedPtr<IHttpRouter> HttpRouter;
|
||||||
|
// Stop The Server
|
||||||
|
void StopServer();
|
||||||
|
// Create the server response
|
||||||
|
TUniquePtr<FHttpServerResponse> CreateHttpServerResponse() const;
|
||||||
|
FHttpModule* HttpRequest;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Implement this for initialization of instances of the system */
|
||||||
|
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||||
|
|
||||||
|
/** Implement this for deinitialization of instances of the system */
|
||||||
|
virtual void Deinitialize() override;
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintAssignable, Category="DTFlux|Subsystem|Events")
|
||||||
|
FDTFluxOnRequestReceived OnRequestReceived;
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintAssignable, Category="DTFlux|Subsystem|Events")
|
||||||
|
FDTFluxOnServerListening OnServerListening;
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintAssignable, Category="DTFlux|Subsystem|Events")
|
||||||
|
FDTFluxOnServerStopped OnServerStopped;
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintAssignable, Category="DTFlux|Subsystem|Events")
|
||||||
|
FDTFluxOnEventStartReceived OnEventStartReceived;
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Subsystem")
|
||||||
|
TArray<FString> GetMountedRoutes() const;
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Subsystem")
|
||||||
|
void StartServer();
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Subsystem|Events")
|
||||||
|
TArray<FDTFluxTeam> GetParticipantsByContestId(const int ContestId );
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Subsystem|Events")
|
||||||
|
TArray<FDTFluxTeam> GetParticipantsByContestName(const FString ContestName);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Subsystem|Events")
|
||||||
|
FString GetContestName(const int ContestId);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Subsystem|Race Result Call")
|
||||||
|
void UpdateStartList();
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Subsystem|Race Result Call")
|
||||||
|
void UpdateClassification(const int& ContestId, const int& StageId = -1);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category="DTFlux|Subsystem|Race Result Call")
|
||||||
|
TArray<FDTFluxParticipant> GetClassification(const int& ContestId, const int& StageId = -1);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
68
Source/DTFluxAPI/Public/DTFluxUtils/DTFluxHttpServerStruct.h
Normal file
68
Source/DTFluxAPI/Public/DTFluxUtils/DTFluxHttpServerStruct.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// Copyright 2023 Dexter.Wan. All Rights Reserved.
|
||||||
|
// EMail: 45141961@qq.com
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
|
#include "DTFluxHttpServerStruct.generated.h"
|
||||||
|
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum EDTFluxHttpServerVerbs : uint8
|
||||||
|
{
|
||||||
|
HTTP_GET,
|
||||||
|
HTTP_POST,
|
||||||
|
HTTP_PUT,
|
||||||
|
HTTP_PATCH,
|
||||||
|
HTTP_DELETE,
|
||||||
|
};
|
||||||
|
|
||||||
|
// USTRUCT(BlueprintType, meta=(DisplayName="DT Http Server Headers", HasNativeBreak = "DTHttpServer.DTHttpServerBPLib.BreakHeaders"))
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Server", meta=(HasNativeBreak = "DTFluxAPI.DTFluxHttpServerBPFn.BreakHeaders"))
|
||||||
|
struct FDTFluxHttpServerHeaders
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
TMap<FString, FString> Headers;
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Server", meta=(HasNativeBreak = "DTFluxAPI.DTFluxHttpServerBPFn.BreakBody"))
|
||||||
|
struct FDTFluxHttpServerBody
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
TArray<uint8> ReqBody;
|
||||||
|
};
|
||||||
|
|
||||||
|
// USTRUCT(BlueprintType, meta=(DisplayName="DTFlux Server Params", HasNativeBreak = "DTHttpServer.DTHttpServerBPLib.BreakParams"))
|
||||||
|
USTRUCT(BlueprintType, Category="DTFlux|Server", meta=(HasNativeBreak = "DTFluxAPI.DTFluxHttpServerBPFn.BreakParams"))
|
||||||
|
struct FDTFluxHttpServerParams
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
TMap<FString, FString> Params;
|
||||||
|
};
|
||||||
|
|
||||||
|
UCLASS(NotBlueprintable, NotBlueprintType)
|
||||||
|
class DTFLUXAPI_API UDTFluxHttpServerBPFn : public UBlueprintFunctionLibrary
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Break DTFlux Http Server Params
|
||||||
|
UFUNCTION(BlueprintPure, meta = (DisplayName="Break Http Server Params"), Category = "DT Http Server|Params")
|
||||||
|
static void BreakParams(const FDTFluxHttpServerParams& HttpServerParams, TMap<FString, FString>& Params);
|
||||||
|
|
||||||
|
// Find DTFlux Http Server Params
|
||||||
|
UFUNCTION(BlueprintPure, meta = (DisplayName="Find Http Server Params"), Category = "DT Http Server|Params")
|
||||||
|
static void FindParam(const FDTFluxHttpServerParams& HttpServerParams, const FString & Key, FString & Param );
|
||||||
|
|
||||||
|
// Break DTFlux Http Server Headers
|
||||||
|
UFUNCTION(BlueprintPure, meta = (DisplayName="Break Http Server Headers"), Category = "DT Http Server|Headers")
|
||||||
|
static void BreakHeaders(const FDTFluxHttpServerHeaders& HttpServerHeaders, TMap<FString, FString>& Headers);
|
||||||
|
|
||||||
|
// Break DTFlux Request Body
|
||||||
|
UFUNCTION(BlueprintPure, meta = (DisplayName="Break Http Server Headers"), Category = "DT Http Server|Headers")
|
||||||
|
static void BreakBody(const FDTFluxHttpServerBody& HttpBody, TArray<uint8> RawBody);
|
||||||
|
|
||||||
|
// Find DTFlux Http Server Headers
|
||||||
|
UFUNCTION(BlueprintPure, meta = (DisplayName="Find Http Server Headers"), Category = "DT Http Server|Headers")
|
||||||
|
static void FindHeader(const FDTFluxHttpServerHeaders& HttpServerHeaders, const FString & Key, FString & Header );
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user