- ServerREST renamed to ServerAPI because it makes a lot more sense that way.

- A bunch of files converted from UTF-16 to UTF-8.
This commit is contained in:
Jamie Greunbaum 2023-03-31 14:47:16 -04:00
parent 7fa9e77c47
commit fd85e22428
11 changed files with 794 additions and 4 deletions

View File

@ -0,0 +1,609 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#include "ServerAPI.h"
#include "HttpModule.h"
#include "JsonObjectConverter.h"
#include "UnrealzillaGlobalSettings.h"
#include "Kismet/GameplayStatics.h"
const FString GetGameVersion()
{
FString GameVersion;
GConfig->GetString(TEXT("/Script/EngineSettings.GeneralProjectSettings"), TEXT("ProjectVersion"), GameVersion, GGameIni);
if (GameVersion.IsEmpty())
{
GameVersion = "1.0.0.0";
}
return GameVersion;
}
void UServerAPI::ReturnListOfBugs()
{
const FString FullURL = GetDefault<UUnrealzillaGlobalSettings>()->SubmissionServer + "/rest.cgi";
TArray<FString> StatusQueries;
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowUnresolvedBugs)
{
for (const FString Unresolved : GetDefault<UUnrealzillaGlobalSettings>()->UnresolvedStatuses)
{
StatusQueries.Add("status=" + Unresolved);
}
}
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowInProgressBugs)
{
for (const FString InProgress : GetDefault<UUnrealzillaGlobalSettings>()->InProgressStatuses)
{
StatusQueries.Add("status=" + InProgress);
}
}
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowResolvedBugs)
{
for (const FString Resolved : GetDefault<UUnrealzillaGlobalSettings>()->ResolvedStatuses)
{
StatusQueries.Add("status=" + Resolved);
}
}
StatusQueries.Add("cf_mapname=" + this->GetWorld()->GetMapName().RightChop(this->GetWorld()->StreamingLevelsPrefix.Len()));
StatusQueries.Add("api_key=" + GetDefault<UUnrealzillaGlobalSettings>()->APIKey);
const FString QueryString = FString::Join(StatusQueries, TEXT("&"));
FHttpModule &HttpModule = FHttpModule::Get();
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> SeverityRequest = HttpModule.CreateRequest();
SeverityRequest->SetVerb(TEXT("GET"));
SeverityRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
SeverityRequest->SetURL(FullURL + "/bug" + "?" + QueryString);
SeverityRequest->OnProcessRequestComplete().BindUObject(this, &UServerAPI::ListOfBugsResponse);
SeverityRequest->ProcessRequest();
}
void UServerAPI::ListOfBugsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
{
if (Success)
{
FBugzillaJSONBugResponse ResponseData;
FString JSONResponse = Response->GetContentAsString();
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
if (!ResponseData.error)
{
TArray<FUnrealzillaBugData> BugData;
for (const FBugzillaJSONBugData &BugzillaData : ResponseData.bugs)
{
FUnrealzillaBugData Bug;
Bug.ID = BugzillaData.id;
Bug.Summary = BugzillaData.summary;
Bug.Component = BugzillaData.component;
Bug.MapName = BugzillaData.cf_mapname;
Bug.MapLocation = BugzillaData.cf_location;
Bug.Platform = BugzillaData.platform;
Bug.OperatingSystem = BugzillaData.op_sys;
Bug.Severity = BugzillaData.severity;
Bug.Status = BugzillaData.status;
Bug.Resolution = BugzillaData.resolution;
Bug.DuplicateOf = BugzillaData.dupe_of;
Bug.bIsOpen = BugzillaData.is_open;
BugData.Add(Bug);
}
this->BugDataResponse.Execute(BugData);
}
else
{
this->CreateError(EErrorVerb::GET, ResponseData);
}
}
}
void UServerAPI::PrepareForm()
{
const FString FullURL = GetDefault<UUnrealzillaGlobalSettings>()->SubmissionServer + "/rest.cgi";
// Assemble query data into key:value pairs
TMap<FString, FString> QueryData;
QueryData.Add("api_key", GetDefault<UUnrealzillaGlobalSettings>()->APIKey);
const FString QueryString = UServerAPI::FormatQueryString(QueryData);
// Query the server for information about the current product
FHttpModule &HttpModule = FHttpModule::Get();
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> ProductRequest = HttpModule.CreateRequest();
ProductRequest->SetVerb(TEXT("GET"));
ProductRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
ProductRequest->SetURL(FullURL + "/product/" + GetDefault<UUnrealzillaGlobalSettings>()->ProductName + "?" + QueryString);
ProductRequest->OnProcessRequestComplete().BindUObject(this, &UServerAPI::ServerProductInfoResponse);
ProductRequest->ProcessRequest();
// Send a second query to retrieve severity options
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> SeverityRequest = HttpModule.CreateRequest();
SeverityRequest->SetVerb(TEXT("GET"));
SeverityRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
SeverityRequest->SetURL(FullURL + "/field/bug/bug_severity" + "?" + QueryString);
SeverityRequest->OnProcessRequestComplete().BindUObject(this, &UServerAPI::ServerSeverityInfoResponse);
SeverityRequest->ProcessRequest();
// Send a third query to retrieve platform options
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> PlatformsRequest = HttpModule.CreateRequest();
PlatformsRequest->SetVerb(TEXT("GET"));
PlatformsRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
PlatformsRequest->SetURL(FullURL + "/field/bug/rep_platform" + "?" + QueryString);
PlatformsRequest->OnProcessRequestComplete().BindUObject(this, &UServerAPI::ServerPlatformInfoResponse);
PlatformsRequest->ProcessRequest();
// Send a final query to retrieve OS options
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> OSRequest = HttpModule.CreateRequest();
OSRequest->SetVerb(TEXT("GET"));
OSRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
OSRequest->SetURL(FullURL + "/field/bug/op_sys" + "?" + QueryString);
OSRequest->OnProcessRequestComplete().BindUObject(this, &UServerAPI::ServerOSInfoResponse);
OSRequest->ProcessRequest();
}
void UServerAPI::SendFormData(const FUnrealzillaPostData &PostData)
{
const FString FullURL = GetDefault<UUnrealzillaGlobalSettings>()->SubmissionServer + "/rest.cgi";
const FString RequestURL = "/bug";
// Assemble query data into key:value pairs
TMap<FString, FString> QueryData;
QueryData.Add("api_key", GetDefault<UUnrealzillaGlobalSettings>()->APIKey);
const FString DefaultStatus = GetDefault<UUnrealzillaGlobalSettings>()->DefaultStatus;
FBugzillaJSONPostBug PostDataJSON;
PostDataJSON.product = GetDefault<UUnrealzillaGlobalSettings>()->ProductName;
PostDataJSON.version = PostData.Version;
PostDataJSON.platform = PostData.Platform;
PostDataJSON.op_sys = PostData.OS;
PostDataJSON.component = PostData.Component;
PostDataJSON.severity = PostData.Severity;
PostDataJSON.cf_mapname = PostData.MapName;
PostDataJSON.cf_location = PostData.MapLocation;
PostDataJSON.summary = PostData.Summary;
PostDataJSON.description = PostData.Comment;
if (!DefaultStatus.IsEmpty())
{
PostDataJSON.status = DefaultStatus;
}
if (PostDataJSON.version.IsEmpty())
{
this->CreateError("You must select a version number.");
return;
}
if (PostDataJSON.platform.IsEmpty() || PostDataJSON.op_sys.IsEmpty())
{
PostDataJSON.platform = "All";
PostDataJSON.op_sys = "All";
}
if (PostDataJSON.component.IsEmpty())
{
this->CreateError("You must select a component.");
return;
}
if (PostDataJSON.severity.IsEmpty())
{
this->CreateError("You must select a severity level.");
return;
}
if (PostDataJSON.summary.IsEmpty())
{
this->CreateError("You must provide a summary.");
return;
}
FString PostJsonString;
FJsonObjectConverter::UStructToJsonObjectString(PostDataJSON, PostJsonString);
FHttpModule &HttpModule = FHttpModule::Get();
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Request = HttpModule.CreateRequest();
Request->SetVerb(TEXT("POST"));
Request->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
Request->SetURL(FullURL + RequestURL + "?" + UServerAPI::FormatQueryString(QueryData));
Request->SetContentAsString(PostJsonString);
Request->OnProcessRequestComplete().BindUObject(this, &UServerAPI::ServerPOSTResponse);
Request->ProcessRequest();
}
void UServerAPI::ServerPOSTResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
{
if (Success)
{
FBugzillaJSONPostResponse ResponseData;
FString JSONResponse = Response->GetContentAsString();
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
if (ResponseData.error)
{
this->CreateError(EErrorVerb::POST, ResponseData);
}
else
{
// Use the response's bug ID to get the info from the newly filed bug report and update its marker
const FString FullURL = GetDefault<UUnrealzillaGlobalSettings>()->SubmissionServer + "/rest.cgi";
TArray<FString> StatusQueries;
StatusQueries.Add("id=" + FString::FromInt(ResponseData.id));
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowUnresolvedBugs)
{
for (const FString Unresolved : GetDefault<UUnrealzillaGlobalSettings>()->UnresolvedStatuses)
{
StatusQueries.Add("status=" + Unresolved);
}
}
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowInProgressBugs)
{
for (const FString InProgress : GetDefault<UUnrealzillaGlobalSettings>()->InProgressStatuses)
{
StatusQueries.Add("status=" + InProgress);
}
}
if (GetDefault<UUnrealzillaGlobalSettings>()->bShowResolvedBugs)
{
for (const FString Resolved : GetDefault<UUnrealzillaGlobalSettings>()->ResolvedStatuses)
{
StatusQueries.Add("status=" + Resolved);
}
}
StatusQueries.Add("cf_mapname=" + this->GetWorld()->GetMapName().RightChop(this->GetWorld()->StreamingLevelsPrefix.Len()));
StatusQueries.Add("api_key=" + GetDefault<UUnrealzillaGlobalSettings>()->APIKey);
const FString QueryString = FString::Join(StatusQueries, TEXT("&"));
FHttpModule &HttpModule = FHttpModule::Get();
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> SeverityRequest = HttpModule.CreateRequest();
SeverityRequest->SetVerb(TEXT("GET"));
SeverityRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
SeverityRequest->SetURL(FullURL + "/bug" + "?" + QueryString);
SeverityRequest->OnProcessRequestComplete().BindUObject(this, &UServerAPI::ServerPOSTUpdateMarkerResponse);
SeverityRequest->ProcessRequest();
}
}
else
{
this->ServerConnectionError(Request->GetStatus());
}
}
void UServerAPI::ServerPOSTUpdateMarkerResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
{
if (Success)
{
FBugzillaJSONBugResponse ResponseData;
FString JSONResponse = Response->GetContentAsString();
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
if (ResponseData.error)
{
this->CreateError(EErrorVerb::GET, ResponseData);
}
else
{
if (!ResponseData.bugs.IsEmpty())
{
TArray<FUnrealzillaBugData> BugData;
FUnrealzillaBugData Bug;
Bug.ID = ResponseData.bugs[0].id;
Bug.Summary = ResponseData.bugs[0].summary;
Bug.Component = ResponseData.bugs[0].component;
Bug.MapName = ResponseData.bugs[0].cf_mapname;
Bug.MapLocation = ResponseData.bugs[0].cf_location;
Bug.Platform = ResponseData.bugs[0].platform;
Bug.OperatingSystem = ResponseData.bugs[0].op_sys;
Bug.Severity = ResponseData.bugs[0].severity;
Bug.Status = ResponseData.bugs[0].status;
Bug.Resolution = ResponseData.bugs[0].resolution;
Bug.DuplicateOf = ResponseData.bugs[0].dupe_of;
Bug.bIsOpen = ResponseData.bugs[0].is_open;
BugData.Add(Bug);
this->BugDataResponse.Execute(BugData);
}
}
}
else
{
this->ServerConnectionError(Request->GetStatus());
}
}
void UServerAPI::ServerProductInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
{
if (Success)
{
FBugzillaJSONProductResponse ResponseData;
FString JSONResponse = Response->GetContentAsString();
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
if (ResponseData.error)
{
//this->ShowProcessingOverlayMessage(ResponseData.message);
this->CreateError(EErrorVerb::GET, ResponseData);
}
else
{
if (!ResponseData.products.IsEmpty())
{
const FBugzillaJSONProductData &ProductData = ResponseData.products[0];
if (ProductData.name == GetDefault<UUnrealzillaGlobalSettings>()->ProductName)
{
for (const FBugzillaJSONComponentData &ComponentData : ProductData.components)
{
this->ComponentsList.Add(ComponentData.name);
}
for (const FBugzillaJSONVersionData &VersionData : ProductData.versions)
{
this->VersionsList.Add(VersionData.name);
}
}
this->CheckIfAllFormResponsesAreIn();
}
else
{
FStringFormatOrderedArguments Args;
Args.Add(FStringFormatArg(GetDefault<UUnrealzillaGlobalSettings>()->ProductName));
//this->ShowProcessingOverlayMessage(FString::Format(TEXT("Could not find data for a product called {0}"), Args), true);
this->CreateError(FString::Format(TEXT("Could not find data for a product called {0}"), Args));
}
}
}
else
{
this->ServerConnectionError(Request->GetStatus());
}
}
void UServerAPI::ServerSeverityInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
{
if (Success)
{
FBugzillaJSONFieldResponse ResponseData;
FString JSONResponse = Response->GetContentAsString();
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
if (ResponseData.error)
{
//this->ShowProcessingOverlayMessage(ResponseData.message);
this->CreateError(EErrorVerb::GET, ResponseData);
}
else
{
if (!ResponseData.fields.IsEmpty() && ResponseData.fields[0].name == "bug_severity")
{
for (const FBugzillaJSONFieldValueData &FieldValue : ResponseData.fields[0].values)
{
this->SeverityList.Add(FieldValue.name);
}
}
this->CheckIfAllFormResponsesAreIn();
}
}
else
{
this->ServerConnectionError(Request->GetStatus());
}
}
void UServerAPI::ServerPlatformInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
{
if (Success)
{
FBugzillaJSONFieldResponse ResponseData;
FString JSONResponse = Response->GetContentAsString();
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
if (ResponseData.error)
{
//this->ShowProcessingOverlayMessage(ResponseData.message);
this->CreateError(EErrorVerb::GET, ResponseData);
}
else
{
if (!ResponseData.fields.IsEmpty() && ResponseData.fields[0].name == "rep_platform")
{
for (const FBugzillaJSONFieldValueData &FieldValue : ResponseData.fields[0].values)
{
this->PlatformsList.Add(FieldValue.name);
}
}
this->CheckIfAllFormResponsesAreIn();
}
}
else
{
this->ServerConnectionError(Request->GetStatus());
}
}
void UServerAPI::ServerOSInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
{
if (Success)
{
FBugzillaJSONFieldResponse ResponseData;
FString JSONResponse = Response->GetContentAsString();
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
if (ResponseData.error)
{
//this->ShowProcessingOverlayMessage(ResponseData.message);
this->CreateError(EErrorVerb::GET, ResponseData);
}
else
{
if (!ResponseData.fields.IsEmpty() && ResponseData.fields[0].name == "op_sys")
{
for (const FBugzillaJSONFieldValueData &FieldValue : ResponseData.fields[0].values)
{
this->OSList.Add(FieldValue.name);
}
}
this->CheckIfAllFormResponsesAreIn();
}
}
else
{
this->ServerConnectionError(Request->GetStatus());
}
}
void UServerAPI::CheckIfAllFormResponsesAreIn()
{
if (!this->ComponentsList.IsEmpty() && !this->VersionsList.IsEmpty() && !this->SeverityList.IsEmpty() &&
!this->PlatformsList.IsEmpty() && !this->OSList.IsEmpty())
{
FUnrealzillaFormPrepData Data;
Data.ComponentsList = this->ComponentsList;
Data.SeverityList = this->SeverityList;
Data.VersionsList = this->VersionsList;
Data.PlatformsList = this->PlatformsList;
Data.OSList = this->OSList;
// Find a default version number to use if possible
if (this->VersionsList.Contains(GetGameVersion()))
{
Data.DetectedVersion = GetGameVersion();
}
else if (this->VersionsList.Contains("unspecified"))
{
Data.DetectedVersion = "unspecified";
}
else if (this->VersionsList.Contains("Latest"))
{
Data.DetectedVersion = "Latest";
}
else if (!this->VersionsList.IsEmpty())
{
Data.DetectedVersion = this->VersionsList[0];
}
// Set these as defaults in case nothing below changes this setting
Data.DetectedHardware = "All";
Data.DetectedOS = "All";
if (this->PlatformsList.Contains("PC"))
{
// Try our best to auto-detect PC hardware
if (UGameplayStatics::GetPlatformName() == "Windows" && this->OSList.Contains("Windows"))
{
Data.DetectedHardware = "PC";
Data.DetectedOS = "Windows";
}
else if (UGameplayStatics::GetPlatformName() == "Linux" && this->OSList.Contains("Linux"))
{
Data.DetectedHardware = "PC";
Data.DetectedOS = "Linux";
}
else if (UGameplayStatics::GetPlatformName() == "Mac" && this->OSList.Contains("Mac OS"))
{
Data.DetectedHardware = "All";
Data.DetectedOS = "Mac OS";
}
}
if (UGameplayStatics::GetPlatformName() == "Mac")
{
// Try our best to auto-detect Macintosh hardware
if (this->PlatformsList.Contains("Macintosh"))
{
if (this->OSList.Contains("Mac OS"))
{
Data.DetectedHardware = "Macintosh";
Data.DetectedOS = "Mac OS";
}
}
}
this->FormDataResponse.Execute(Data);
this->ComponentsList.Empty();
this->VersionsList.Empty();
this->SeverityList.Empty();
this->PlatformsList.Empty();
this->OSList.Empty();
}
}
void UServerAPI::ServerConnectionError(const EHttpRequestStatus::Type Status)
{
switch (Status) {
case EHttpRequestStatus::Failed_ConnectionError:
this->CreateError("Unable to connect to the server");
//this->ShowProcessingOverlayMessage("Unable to connect to the server", true);
break;
case EHttpRequestStatus::NotStarted:
this->CreateError("Connection could not start");
//this->ShowProcessingOverlayMessage("Connection could not start", true);
break;
case EHttpRequestStatus::Failed:
this->CreateError("Connection failed");
//this->ShowProcessingOverlayMessage("Connection failed", true);
break;
default:
this->CreateError("Request failed for unknown reasons");
//this->ShowProcessingOverlayMessage("Request failed for unknown reasons", true);
}
}
void UServerAPI::CreateError(const EErrorVerb &Verb, const FBugzillaJSONPostResponse &Data)
{
FUnrealzillaErrorData Error;
Error.ErrorVerb = Verb;
Error.ErrorCode = Data.code;
Error.ErrorMessage = Data.message;
Error.DocumentationLink = Data.documentation;
this->ErrorResponse.Execute(Error);
}
void UServerAPI::CreateError(const EErrorVerb &Verb, const FBugzillaJSONProductResponse &Data)
{
FUnrealzillaErrorData Error;
Error.ErrorVerb = Verb;
Error.ErrorCode = Data.code;
Error.ErrorMessage = Data.message;
Error.DocumentationLink = Data.documentation;
this->ErrorResponse.Execute(Error);
}
void UServerAPI::CreateError(const EErrorVerb &Verb, const FBugzillaJSONFieldResponse &Data)
{
FUnrealzillaErrorData Error;
Error.ErrorVerb = Verb;
Error.ErrorCode = Data.code;
Error.ErrorMessage = Data.message;
Error.DocumentationLink = Data.documentation;
this->ErrorResponse.Execute(Error);
}
void UServerAPI::CreateError(const EErrorVerb &Verb, const FBugzillaJSONBugResponse &Data)
{
FUnrealzillaErrorData Error;
Error.ErrorVerb = Verb;
Error.ErrorCode = Data.code;
Error.ErrorMessage = Data.message;
Error.DocumentationLink = Data.documentation;
this->ErrorResponse.Execute(Error);
}
void UServerAPI::CreateError(const FString &ErrorMessage)
{
FUnrealzillaErrorData Error;
Error.ErrorVerb = EErrorVerb::None;
Error.ErrorMessage = ErrorMessage;
this->ErrorResponse.Execute(Error);
}
const FString UServerAPI::FormatQueryString(const TMap<FString, FString> &QueryData)
{
TArray<FString> AssembledKeyValuePairs;
TArray<FString> QueryKeys;
QueryData.GenerateKeyArray(QueryKeys);
for (const FString &QueryKey : QueryKeys)
{
AssembledKeyValuePairs.Add(QueryKey + "=" + QueryData[QueryKey]);
}
return FString::Join(AssembledKeyValuePairs, TEXT("&"));
}

View File

@ -1,4 +1,4 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved. // ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#include "UnrealzillaGlobalSettings.h" #include "UnrealzillaGlobalSettings.h"

View File

@ -1,4 +1,4 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved. // ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#pragma once #pragma once

View File

@ -1,4 +1,4 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved. // ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#pragma once #pragma once

View File

@ -0,0 +1,113 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "UnrealzillaBugDataStructs.generated.h"
UENUM(Blueprintable)
enum class EErrorVerb : uint8
{
None UMETA(DisplayName="None"),
GET UMETA(DisplayName="GET"),
POST UMETA(DisplayName="POST"),
MAX UMETA(Hidden)
};
USTRUCT(Blueprintable)
struct FUnrealzillaErrorData
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly)
EErrorVerb ErrorVerb = EErrorVerb::None;
UPROPERTY(BlueprintReadOnly)
int32 ErrorCode = -1;
UPROPERTY(BlueprintReadOnly)
FString ErrorMessage;
UPROPERTY(BlueprintReadOnly)
FString DocumentationLink;
};
USTRUCT(Blueprintable)
struct FUnrealzillaBugData
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly)
int32 ID = -1;
UPROPERTY(BlueprintReadOnly)
FString Summary;
UPROPERTY(BlueprintReadOnly)
FString Component;
UPROPERTY(BlueprintReadOnly)
FString MapName;
UPROPERTY(BlueprintReadOnly)
FString MapLocation;
UPROPERTY(BlueprintReadOnly)
FString Platform;
UPROPERTY(BlueprintReadOnly)
FString OperatingSystem;
UPROPERTY(BlueprintReadOnly)
bool bIsOpen = true;
UPROPERTY(BlueprintReadOnly)
FString Severity;
UPROPERTY(BlueprintReadOnly)
FString Status;
UPROPERTY(BlueprintReadOnly)
FString Resolution;
UPROPERTY(BlueprintReadOnly)
int32 DuplicateOf = -1;
};
USTRUCT(Blueprintable)
struct FUnrealzillaFormPrepData
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly)
TArray<FString> ComponentsList;
UPROPERTY(BlueprintReadOnly)
TArray<FString> SeverityList;
UPROPERTY(BlueprintReadOnly)
TArray<FString> VersionsList;
UPROPERTY(BlueprintReadOnly)
TArray<FString> PlatformsList;
UPROPERTY(BlueprintReadOnly)
TArray<FString> OSList;
UPROPERTY(BlueprintReadOnly)
FString DetectedVersion;
UPROPERTY(BlueprintReadOnly)
FString DetectedHardware;
UPROPERTY(BlueprintReadOnly)
FString DetectedOS;
};
USTRUCT(Blueprintable)
struct FUnrealzillaPostData
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly)
FString Version;
UPROPERTY(BlueprintReadOnly)
FString Platform;
UPROPERTY(BlueprintReadOnly)
FString OS;
UPROPERTY(BlueprintReadOnly)
FString Component;
UPROPERTY(BlueprintReadOnly)
FString Severity;
UPROPERTY(BlueprintReadOnly)
FString MapName;
UPROPERTY(BlueprintReadOnly)
FString MapLocation;
UPROPERTY(BlueprintReadOnly)
FString Summary;
UPROPERTY(BlueprintReadOnly)
FString Comment;
};

View File

@ -4,7 +4,7 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "ServerREST.h" #include "ServerAPI.h"
#include "BugMarkerActor.generated.h" #include "BugMarkerActor.generated.h"

View File

@ -0,0 +1,68 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "API/BugzillaJSONStructs.h"
#include "API/UnrealzillaBugDataStructs.h"
#include "Interfaces/IHttpRequest.h"
#include "Interfaces/IHttpResponse.h"
#include "ServerAPI.generated.h"
/**
* Class for communicating with REST API on bug tracking software
*/
UCLASS()
class UNREALZILLA_API UServerAPI : public UObject
{
GENERATED_BODY()
public:
void ReturnListOfBugs();
void PrepareForm();
void SendFormData(const FUnrealzillaPostData &PostData);
DECLARE_DELEGATE_OneParam(FBugListResponseDelegate, const TArray<FUnrealzillaBugData>&);
FBugListResponseDelegate BugDataResponse;
DECLARE_DELEGATE_OneParam(FFormResponseDelegate, const FUnrealzillaFormPrepData&);
FFormResponseDelegate FormDataResponse;
DECLARE_DELEGATE_OneParam(FServerErrorResponseDelegate, const FUnrealzillaErrorData &)
FServerErrorResponseDelegate ErrorResponse;
TArray<FString> GetComponentsList() const { return this->ComponentsList; }
TArray<FString> GetSeverityList() const { return this->SeverityList; }
TArray<FString> GetVersionsList() const { return this->VersionsList; }
TArray<FString> GetPlatformsList() const { return this->PlatformsList; }
TArray<FString> GetOSList() const { return this->OSList; }
private:
void ListOfBugsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
void ServerPOSTResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
void ServerPOSTUpdateMarkerResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
void ServerProductInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
void ServerSeverityInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
void ServerPlatformInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
void ServerOSInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
void CheckIfAllFormResponsesAreIn();
void ServerConnectionError(const EHttpRequestStatus::Type Status);
void CreateError(const EErrorVerb &Verb, const FBugzillaJSONPostResponse &Data);
void CreateError(const EErrorVerb &Verb, const FBugzillaJSONProductResponse &Data);
void CreateError(const EErrorVerb &Verb, const FBugzillaJSONFieldResponse &Data);
void CreateError(const EErrorVerb &Verb, const FBugzillaJSONBugResponse &Data);
void CreateError(const FString &ErrorMessage);
static const FString FormatQueryString(const TMap<FString, FString> &QueryData);
TArray<FString> ComponentsList;
TArray<FString> SeverityList;
TArray<FString> VersionsList;
TArray<FString> PlatformsList;
TArray<FString> OSList;
};