Reworked a whole lot of code so that we can eventually add more than just Bugzilla support to the plugin.

This commit is contained in:
Jamie Greunbaum 2023-03-30 18:59:16 -04:00
parent 3f20507962
commit 5816ec390b
21 changed files with 98 additions and 672 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -10,15 +10,15 @@
EBugStatus ABugMarkerActor::GetBugStatus() const
{
if (GetDefault<UUnrealzillaGlobalSettings>()->ResolvedStatuses.Contains(this->BugData.status))
if (GetDefault<UUnrealzillaGlobalSettings>()->ResolvedStatuses.Contains(this->BugData.Status))
{
return EBugStatus::Resolved;
}
else if (GetDefault<UUnrealzillaGlobalSettings>()->InProgressStatuses.Contains(this->BugData.status))
else if (GetDefault<UUnrealzillaGlobalSettings>()->InProgressStatuses.Contains(this->BugData.Status))
{
return EBugStatus::InProgress;
}
else if (GetDefault<UUnrealzillaGlobalSettings>()->UnresolvedStatuses.Contains(this->BugData.status))
else if (GetDefault<UUnrealzillaGlobalSettings>()->UnresolvedStatuses.Contains(this->BugData.Status))
{
return EBugStatus::Unresolved;
}

View File

@ -1,150 +0,0 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#include "BugMarkerLoader.h"
#include "BugMarkerActor.h"
#include "HttpModule.h"
#include "JsonObjectConverter.h"
#include "UnrealzillaGlobalSettings.h"
#include "Kismet/GameplayStatics.h"
void ABugMarkerLoader::BeginPlay()
{
Super::BeginPlay();
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, &ABugMarkerLoader::ServerBugResponse);
SeverityRequest->ProcessRequest();
}
void ABugMarkerLoader::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
this->GetWorldTimerManager().ClearTimer(this->NewBatchTimerHandle);
this->GetWorldTimerManager().ClearTimer(this->UnloadAllTimerHandle);
Super::EndPlay(EndPlayReason);
}
void ABugMarkerLoader::ServerBugResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
{
if (Success)
{
FJSONBugResponse ResponseData;
FString JSONResponse = Response->GetContentAsString();
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
if (ResponseData.error)
{
this->Destroy();
return;
}
else
{
this->BugBatch = ResponseData.bugs;
this->GetWorldTimerManager().SetTimer(this->NewBatchTimerHandle, this, &ABugMarkerLoader::LoadNewBatch, 1.0f/*this->GetWorld()->GetDeltaSeconds()*/);
}
}
else
{
this->Destroy();
return;
}
}
void ABugMarkerLoader::LoadNewBatch()
{
while (!this->BugBatch.IsEmpty())
{
const FJSONBugData BugData = this->BugBatch[0];
FString LocationString, UpVectorString;
BugData.cf_location.Split(":", &LocationString, &UpVectorString);
FString LocationX, LocationY, LocationZ;
LocationString.Split(",", &LocationX, &LocationY);
LocationY.Split(",", &LocationY, &LocationZ);
FString UpVectorX, UpVectorY, UpVectorZ;
UpVectorString.Split(",", &UpVectorX, &UpVectorY);
UpVectorY.Split(",", &UpVectorY, &UpVectorZ);
const FVector Location(FCString::Atof(*LocationX),FCString::Atof(*LocationY),FCString::Atof(*LocationZ));
const FVector UpVector(FCString::Atof(*UpVectorX),FCString::Atof(*UpVectorY),FCString::Atof(*UpVectorZ));
TSubclassOf<ABugMarkerActor> Class = StaticLoadClass(ABugMarkerActor::StaticClass(), this, BUG_MARKER_ACTOR_BP);
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
const FTransform Transform = FTransform(FRotationMatrix::MakeFromZ(UpVector).Rotator(), Location, FVector::OneVector);
ABugMarkerActor *Marker = this->GetWorld()->SpawnActor<ABugMarkerActor>(Class, Transform, SpawnParams);
Marker->SetBugData(BugData);
this->Markers.Add(Marker);
this->BugBatch.RemoveAt(0);
if (!(this->BugBatch.Num() % GetDefault<UUnrealzillaGlobalSettings>()->LoadMarkersBatch))
{
break;
}
}
if (!this->BugBatch.IsEmpty())
{
this->GetWorldTimerManager().SetTimer(this->NewBatchTimerHandle, this, &ABugMarkerLoader::LoadNewBatch, this->GetWorld()->GetDeltaSeconds());
}
}
void ABugMarkerLoader::UnloadAll()
{
this->GetWorldTimerManager().ClearTimer(this->NewBatchTimerHandle);
while (!this->Markers.IsEmpty())
{
AActor *Marker = this->Markers[0];
this->Markers.RemoveAt(0);
Marker->Destroy();
if (!(this->Markers.Num() % GetDefault<UUnrealzillaGlobalSettings>()->UnloadMarkersBatch))
{
break;
}
}
if (!this->Markers.IsEmpty())
{
this->GetWorldTimerManager().SetTimer(this->UnloadAllTimerHandle, this, &ABugMarkerLoader::UnloadAll, this->GetWorld()->GetDeltaSeconds());
}
else
{
this->Destroy();
}
}

Binary file not shown.

View File

@ -3,10 +3,10 @@
#include "BugPlacerPawn.h"
#include "BugMarkerActor.h"
#include "BugMarkerLoader.h"
#include "BugMarkerSubsystem.h"
#include "ExitingBugPlacementScreen.h"
#include "UnrealzillaGlobalSettings.h"
#include "UnrealzillaJSON.h"
#include "BugzillaJSONStructs.h"
#include "Components/MaterialBillboardComponent.h"
#include "Components/SphereComponent.h"
@ -100,7 +100,7 @@ void ABugPlacerPawn::TraceTimerElapsed()
else
{
this->PlacementMarkerRoot->SetVisibility(true, true);
this->UpdateBugInformation(FJSONBugData());
this->UpdateBugInformation(FUnrealzillaBugData());
this->ShowDummyMarker(true);
}
@ -209,31 +209,16 @@ void ABugPlacerPawn::SpawnBugPlacerPawn(const UObject *WorldContextObject, TSubc
void ABugPlacerPawn::ShowBugMarkersInLevel(const UObject *WorldContextObject)
{
for (TActorIterator<AActor> Iterator(WorldContextObject->GetWorld(), ABugMarkerLoader::StaticClass()); Iterator; ++Iterator)
if (UBugMarkerSubsystem *BugMarkerSubsystem = UGameplayStatics::GetPlayerController(WorldContextObject, 0)->GetLocalPlayer()->GetSubsystem<UBugMarkerSubsystem>())
{
return;
BugMarkerSubsystem->ShowBugMarkers();
}
WorldContextObject->GetWorld()->SpawnActor<ABugMarkerLoader>(ABugMarkerLoader::StaticClass(), FVector::ZeroVector, FRotator::ZeroRotator);
}
void ABugPlacerPawn::HideBugMarkersInLevel(const UObject *WorldContextObject)
{
for (TActorIterator<AActor> Iterator(WorldContextObject->GetWorld(), ABugMarkerLoader::StaticClass()); Iterator; ++Iterator)
if (UBugMarkerSubsystem *BugMarkerSubsystem = UGameplayStatics::GetPlayerController(WorldContextObject, 0)->GetLocalPlayer()->GetSubsystem<UBugMarkerSubsystem>())
{
ABugMarkerLoader *BugMarkerLoader = Cast<ABugMarkerLoader>(*Iterator);
BugMarkerLoader->UnloadAll();
BugMarkerSubsystem->HideBugMarkers();
}
}
const FString ABugPlacerPawn::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

@ -3,13 +3,13 @@
#include "BugSubmissionForm.h"
#include "BugMarkerActor.h"
#include "BugPlacerPawn.h"
//#include "BugPlacerPawn.h"
#include "BugMarkerSubsystem.h"
#include "CommonButtonBase.h"
#include "CommonTextBlock.h"
#include "HttpModule.h"
#include "JsonObjectConverter.h"
#include "UnrealzillaGlobalSettings.h"
#include "UnrealzillaJSON.h"
#include "Components/CircularThrobber.h"
#include "Components/Overlay.h"
@ -33,67 +33,33 @@ const FText FormatFloatToText(float Float, int32 IntegralDigits, int32 Fractiona
return FText::AsNumber(Float, &NumberFormat);
}
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 UBugSubmissionForm::NativeOnInitialized()
{
this->ShowProcessingOverlayLoading();
this->ProductNameValue->SetText(FText::AsCultureInvariant(GetDefault<UUnrealzillaGlobalSettings>()->ProductName));
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 = ABugPlacerPawn::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, &UBugSubmissionForm::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, &UBugSubmissionForm::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, &UBugSubmissionForm::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, &UBugSubmissionForm::ServerOSInfoResponse);
OSRequest->ProcessRequest();
UBugMarkerSubsystem *BugMarkerSubsystem = UGameplayStatics::GetPlayerController(this, 0)->GetLocalPlayer()->GetSubsystem<UBugMarkerSubsystem>();
BugMarkerSubsystem->FormPrepResponse.BindUObject(this, &UBugSubmissionForm::PrepareFormData);
BugMarkerSubsystem->PrepareSubmissionFormData();
this->SubmitButton->OnClicked().AddUObject(this, &UBugSubmissionForm::SubmitForm);
this->CancelButton->OnClicked().AddUObject(this, &UBugSubmissionForm::CancelForm);
}
void UBugSubmissionForm::PrepareFormData(const FUnrealzillaFormPrepData &Data)
{
this->ComponentsList = Data.ComponentsList;
this->SeverityList = Data.SeverityList;
this->VersionsList = Data.VersionsList;
this->PlatformsList = Data.PlatformsList;
this->OSList = Data.OSList;
this->VersionButton->SetText(FText::AsCultureInvariant(Data.DetectedVersion));
this->HardwareButton->SetText(FText::AsCultureInvariant(Data.DetectedHardware));
this->OSButton->SetText(FText::AsCultureInvariant(Data.DetectedOS));
this->HideProcessingOverlay();
}
void UBugSubmissionForm::SetMarkerData(ABugMarkerActor *BugMarker)
@ -153,74 +119,30 @@ void UBugSubmissionForm::SubmitForm()
{
this->ShowProcessingOverlayLoading();
const FString FullURL = GetDefault<UUnrealzillaGlobalSettings>()->SubmissionServer + "/rest.cgi";
const FString RequestURL = "/bug";
FUnrealzillaPostData PostData;
PostData.Version = this->VersionButton->GetText().ToString();
PostData.Platform = this->HardwareButton->GetText().ToString();
PostData.OS = this->OSButton->GetText().ToString();
PostData.Component = this->ComponentButton->GetText().ToString();
PostData.Severity = this->SeverityButton->GetText().ToString();
PostData.MapName = this->MapName.ToString();
PostData.MapLocation = this->MarkerLocation.ToString();
PostData.Summary = this->SummaryEntryBox->GetText().ToString();
PostData.Comment = this->CommentEntryBox->GetText().ToString();
// Assemble query data into key:value pairs
TMap<FString, FString> QueryData;
QueryData.Add("api_key", GetDefault<UUnrealzillaGlobalSettings>()->APIKey);
const FString SummaryText = this->SummaryEntryBox->GetText().ToString();
const FString CommentText = this->CommentEntryBox->GetText().ToString();
const FString DefaultStatus = GetDefault<UUnrealzillaGlobalSettings>()->DefaultStatus;
FString PostJsonString;
FJSONPostBug PostData;
PostData.product = GetDefault<UUnrealzillaGlobalSettings>()->ProductName;
PostData.version = this->VersionButton->GetText().ToString();
PostData.platform = this->HardwareButton->GetText().ToString();
PostData.op_sys = this->OSButton->GetText().ToString();
PostData.component = this->ComponentButton->GetText().ToString();
PostData.severity = this->SeverityButton->GetText().ToString();
PostData.cf_mapname = this->MapName.ToString();
PostData.cf_location = this->MarkerLocation.ToString();
PostData.summary = SummaryText;
PostData.description = CommentText;
if (!DefaultStatus.IsEmpty())
{
PostData.status = DefaultStatus;
}
FJsonObjectConverter::UStructToJsonObjectString(PostData, PostJsonString);
if (PostData.version.IsEmpty())
{
this->ShowProcessingOverlayMessage("You must select a version number.");
return;
}
if (PostData.platform.IsEmpty() || PostData.op_sys.IsEmpty())
{
PostData.platform = "All";
PostData.op_sys = "All";
}
if (PostData.component.IsEmpty())
{
this->ShowProcessingOverlayMessage("You must select a component.");
return;
}
if (PostData.severity.IsEmpty())
{
this->ShowProcessingOverlayMessage("You must select a severity level.");
return;
}
if (SummaryText.IsEmpty())
{
this->ShowProcessingOverlayMessage("You must provide a summary.");
return;
}
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 + "?" + ABugPlacerPawn::FormatQueryString(QueryData));
Request->SetContentAsString(PostJsonString);
Request->OnProcessRequestComplete().BindUObject(this, &UBugSubmissionForm::ServerPOSTResponse);
Request->ProcessRequest();
UBugMarkerSubsystem *BugMarkerSubsystem = UGameplayStatics::GetPlayerController(this, 0)->GetLocalPlayer()->GetSubsystem<UBugMarkerSubsystem>();
BugMarkerSubsystem->FormPostResponse.BindUObject(this, &UBugSubmissionForm::UpdateReportMarker);
BugMarkerSubsystem->SubmitForm(PostData);
this->OnFormSubmit.ExecuteIfBound();
}
void UBugSubmissionForm::UpdateReportMarker(const FUnrealzillaBugData &BugData)
{
this->BugMarkerActor->SetBugData(BugData);
this->CloseForm();
}
void UBugSubmissionForm::CancelForm()
{
this->OnFormCancelled.ExecuteIfBound();
@ -238,302 +160,7 @@ void UBugSubmissionForm::CloseForm()
}
void UBugSubmissionForm::ServerPOSTResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
void UBugSubmissionForm::ErrorResponseCallback(const FUnrealzillaErrorData &Error)
{
if (Success)
{
FJSONPostResponse ResponseData;
FString JSONResponse = Response->GetContentAsString();
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
if (ResponseData.error)
{
this->ShowProcessingOverlayMessage(ResponseData.message);
}
else
{
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, &UBugSubmissionForm::ServerPOSTUpdateMarkerResponse);
SeverityRequest->ProcessRequest();
}
}
else
{
this->ServerConnectionError(Request->GetStatus());
}
}
void UBugSubmissionForm::ServerPOSTUpdateMarkerResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
{
if (Success)
{
FJSONBugResponse ResponseData;
FString JSONResponse = Response->GetContentAsString();
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
if (ResponseData.error)
{
this->ShowProcessingOverlayMessage(ResponseData.message);
}
else
{
if (!ResponseData.bugs.IsEmpty())
{
this->BugMarkerActor->SetBugData(ResponseData.bugs[0]);
}
this->CloseForm();
}
}
else
{
this->ServerConnectionError(Request->GetStatus());
}
}
void UBugSubmissionForm::ServerProductInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
{
if (Success)
{
FJSONProductResponse ResponseData;
FString JSONResponse = Response->GetContentAsString();
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
if (ResponseData.error)
{
this->ShowProcessingOverlayMessage(ResponseData.message);
}
else
{
if (!ResponseData.products.IsEmpty())
{
const FJSONProductData &ProductData = ResponseData.products[0];
if (ProductData.name == GetDefault<UUnrealzillaGlobalSettings>()->ProductName)
{
for (const FJSONComponentData &ComponentData : ProductData.components)
{
this->ComponentList.Add(ComponentData.name);
}
for (const FJSONVersionData &VersionData : ProductData.versions)
{
this->VersionsList.Add(VersionData.name);
}
}
if (this->VersionsList.Contains(GetGameVersion()))
{
this->VersionButton->SetText(FText::AsCultureInvariant(GetGameVersion()));
}
else if (this->VersionsList.Contains("unspecified"))
{
this->VersionButton->SetText(FText::AsCultureInvariant("unspecified"));
}
else if (this->VersionsList.Contains("Latest"))
{
this->VersionButton->SetText(FText::AsCultureInvariant("Latest"));
}
else if (!this->VersionsList.IsEmpty())
{
this->VersionButton->SetText(FText::AsCultureInvariant(this->VersionsList[0]));
}
this->CheckIfAllInitialResponsesAreIn();
}
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);
}
}
}
else
{
this->ServerConnectionError(Request->GetStatus());
}
}
void UBugSubmissionForm::ServerSeverityInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
{
if (Success)
{
FJSONFieldResponse ResponseData;
FString JSONResponse = Response->GetContentAsString();
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
if (ResponseData.error)
{
this->ShowProcessingOverlayMessage(ResponseData.message);
}
else
{
if (!ResponseData.fields.IsEmpty() && ResponseData.fields[0].name == "bug_severity")
{
for (const FJSONFieldValueData &FieldValue : ResponseData.fields[0].values)
{
this->SeverityList.Add(FieldValue.name);
}
}
this->CheckIfAllInitialResponsesAreIn();
}
}
else
{
this->ServerConnectionError(Request->GetStatus());
}
}
void UBugSubmissionForm::ServerPlatformInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
{
if (Success)
{
FJSONFieldResponse ResponseData;
FString JSONResponse = Response->GetContentAsString();
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
if (ResponseData.error)
{
this->ShowProcessingOverlayMessage(ResponseData.message);
}
else
{
if (!ResponseData.fields.IsEmpty() && ResponseData.fields[0].name == "rep_platform")
{
for (const FJSONFieldValueData &FieldValue : ResponseData.fields[0].values)
{
this->PlatformsList.Add(FieldValue.name);
}
}
this->CheckIfAllInitialResponsesAreIn();
}
}
else
{
this->ServerConnectionError(Request->GetStatus());
}
}
void UBugSubmissionForm::ServerOSInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success)
{
if (Success)
{
FJSONFieldResponse ResponseData;
FString JSONResponse = Response->GetContentAsString();
FJsonObjectConverter::JsonObjectStringToUStruct(JSONResponse, &ResponseData);
if (ResponseData.error)
{
this->ShowProcessingOverlayMessage(ResponseData.message);
}
else
{
if (!ResponseData.fields.IsEmpty() && ResponseData.fields[0].name == "op_sys")
{
for (const FJSONFieldValueData &FieldValue : ResponseData.fields[0].values)
{
this->OSList.Add(FieldValue.name);
}
}
this->CheckIfAllInitialResponsesAreIn();
}
}
else
{
this->ServerConnectionError(Request->GetStatus());
}
}
void UBugSubmissionForm::CheckIfAllInitialResponsesAreIn()
{
if (!this->ComponentList.IsEmpty() && !this->VersionsList.IsEmpty() && !this->SeverityList.IsEmpty() &&
!this->PlatformsList.IsEmpty() && !this->OSList.IsEmpty())
{
// Set these as defaults in case nothing below changes this setting
this->HardwareButton->SetText(FText::AsCultureInvariant("All"));
this->OSButton->SetText(FText::AsCultureInvariant("All"));
if (this->PlatformsList.Contains("PC")) // Try our best to auto-detect PC hardware
{
if (UGameplayStatics::GetPlatformName() == "Windows" && this->OSList.Contains("Windows"))
{
this->HardwareButton->SetText(FText::AsCultureInvariant("PC"));
this->OSButton->SetText(FText::AsCultureInvariant("Windows"));
}
else if (UGameplayStatics::GetPlatformName() == "Linux" && this->OSList.Contains("Linux"))
{
this->HardwareButton->SetText(FText::AsCultureInvariant("PC"));
this->OSButton->SetText(FText::AsCultureInvariant("Linux"));
}
else if (UGameplayStatics::GetPlatformName() == "Mac" && this->OSList.Contains("Mac OS"))
{
this->HardwareButton->SetText(FText::AsCultureInvariant("All"));
this->OSButton->SetText(FText::AsCultureInvariant("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"))
{
this->HardwareButton->SetText(FText::AsCultureInvariant("Macintosh"));
this->OSButton->SetText(FText::AsCultureInvariant("Mac OS"));
}
}
}
this->HideProcessingOverlay();
}
}
void UBugSubmissionForm::ServerConnectionError(const EHttpRequestStatus::Type Status)
{
switch (Status) {
case EHttpRequestStatus::Failed_ConnectionError:
this->ShowProcessingOverlayMessage("Unable to connect to the server", true);
break;
case EHttpRequestStatus::NotStarted:
this->ShowProcessingOverlayMessage("Connection could not start", true);
break;
case EHttpRequestStatus::Failed:
this->ShowProcessingOverlayMessage("Connection failed", true);
break;
default:
this->ShowProcessingOverlayMessage("Request failed for unknown reasons", true);
}
this->ShowProcessingOverlayMessage(Error.ErrorMessage);
}

Binary file not shown.

View File

@ -3,7 +3,8 @@
#pragma once
#include "CoreMinimal.h"
#include "UnrealzillaJSON.h"
#include "ServerREST.h"
#include "BugMarkerActor.generated.h"
@ -32,12 +33,12 @@ public:
void LoadBugSubmissionForm();
UFUNCTION(BlueprintCallable)
void SetBugData(const FJSONBugData &Data) { this->BugData = Data; this->ReloadBugData(); }
void SetBugData(const FUnrealzillaBugData &Data) { this->BugData = Data; this->ReloadBugData(); }
UFUNCTION(BlueprintPure)
FJSONBugData GetBugData() const { return this->BugData; }
FUnrealzillaBugData GetBugData() const { return this->BugData; }
UFUNCTION(BlueprintPure)
EBugStatus GetBugStatus() const;
protected:
FJSONBugData BugData;
FUnrealzillaBugData BugData;
};

View File

@ -1,34 +0,0 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "UnrealzillaJSON.h"
#include "Interfaces/IHttpRequest.h"
#include "Interfaces/IHttpResponse.h"
#include "BugMarkerLoader.generated.h"
UCLASS()
class UNREALZILLA_API ABugMarkerLoader : public AActor
{
GENERATED_BODY()
public:
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
void UnloadAll();
private:
void ServerBugResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
void LoadNewBatch();
TArray<AActor*> Markers;
TArray<FJSONBugData> BugBatch;
FTimerHandle NewBatchTimerHandle;
FTimerHandle UnloadAllTimerHandle;
};

Binary file not shown.

View File

@ -3,7 +3,7 @@
#pragma once
#include "CoreMinimal.h"
#include "UnrealzillaJSON.h"
#include "BugzillaJSONStructs.h"
#include "GameFramework/Pawn.h"
#include "BugPlacerPawn.generated.h"
@ -27,7 +27,7 @@ public:
void Deactivate();
UFUNCTION(BlueprintImplementableEvent)
void UpdateBugInformation(const FJSONBugData &BugData);
void UpdateBugInformation(const FUnrealzillaBugData &BugData);
UFUNCTION(BlueprintImplementableEvent)
void ShowDummyMarker(const bool bShow);
UFUNCTION(BlueprintImplementableEvent)
@ -40,9 +40,6 @@ public:
UFUNCTION(BlueprintCallable, meta=(WorldContext="WorldContextObject"))
static void HideBugMarkersInLevel(const UObject *WorldContextObject);
UFUNCTION(BlueprintPure)
static const FString FormatQueryString(const TMap<FString, FString> &QueryData);
protected:
UFUNCTION(BlueprintCallable)
void SetArbitraryPlacement(bool bSet);

View File

@ -6,7 +6,7 @@
#include "BugFormButton.h"
#include "CommonActivatableWidget.h"
#include "UnrealzillaJSON.h"
#include "BugzillaJSONStructs.h"
#include "Interfaces/IHttpRequest.h"
#include "Interfaces/IHttpResponse.h"
@ -30,7 +30,7 @@ protected:
virtual void NativeOnInitialized() override;
UFUNCTION(BlueprintImplementableEvent, meta=(DisplayName="Display POST Response"))
void DisplayPOSTResponse(const FJSONPostResponse &Response);
void DisplayPOSTResponse(const FBugzillaJSONPostResponse &Response);
UPROPERTY(BlueprintReadOnly, meta=(BindWidget))
TObjectPtr<class UCommonTextBlock> ProductNameValue;
@ -67,26 +67,18 @@ protected:
UPROPERTY(BlueprintReadOnly, meta=(BindWidget))
TObjectPtr<class UCommonButtonBase> ProcessingRequestErrorButton;
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)
TArray<FString> ComponentList;
UPROPERTY(BlueprintReadOnly)
TArray<FString> SeverityList;
private:
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 CheckIfAllInitialResponsesAreIn();
UFUNCTION(BlueprintCallable)
void ShowProcessingOverlayLoading();
UFUNCTION(BlueprintCallable)
@ -101,7 +93,9 @@ private:
void CloseForm();
void ServerConnectionError(const EHttpRequestStatus::Type Status);
void PrepareFormData(const struct FUnrealzillaFormPrepData &Data);
void ErrorResponseCallback(const struct FUnrealzillaErrorData &Error);
void UpdateReportMarker(const struct FUnrealzillaBugData &BugData);
FText MapName;
FText MarkerLocation;

View File

@ -4,14 +4,14 @@
#include "CoreMinimal.h"
#include "UnrealzillaJSON.generated.h"
#include "BugzillaJSONStructs.generated.h"
/**
* JSON structs for POST
*/
USTRUCT()
struct FJSONPostBug
struct FBugzillaJSONPostBug
{
GENERATED_BODY()
public:
@ -40,7 +40,7 @@ public:
};
USTRUCT(Blueprintable)
struct FJSONPostResponse
struct FBugzillaJSONPostResponse
{
GENERATED_BODY()
public:
@ -64,7 +64,7 @@ public:
* JSON structs for product data
*/
USTRUCT(Blueprintable)
struct FJSONComponentData
struct FBugzillaJSONComponentData
{
GENERATED_BODY()
public:
@ -83,7 +83,7 @@ public:
};
USTRUCT(Blueprintable)
struct FJSONVersionData
struct FBugzillaJSONVersionData
{
GENERATED_BODY()
public:
@ -98,7 +98,7 @@ public:
};
USTRUCT(Blueprintable)
struct FJSONProductData
struct FBugzillaJSONProductData
{
GENERATED_BODY()
public:
@ -109,18 +109,18 @@ public:
UPROPERTY(BlueprintReadOnly)
FString description;
UPROPERTY(BlueprintReadOnly)
TArray<FJSONComponentData> components;
TArray<FBugzillaJSONComponentData> components;
UPROPERTY(BlueprintReadOnly)
TArray<FJSONVersionData> versions;
TArray<FBugzillaJSONVersionData> versions;
};
USTRUCT(Blueprintable)
struct FJSONProductResponse
struct FBugzillaJSONProductResponse
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly)
TArray<FJSONProductData> products;
TArray<FBugzillaJSONProductData> products;
UPROPERTY(BlueprintReadOnly)
bool error = false;
@ -140,7 +140,7 @@ public:
* JSON structs for product data
*/
USTRUCT(Blueprintable)
struct FJSONFieldValueData
struct FBugzillaJSONFieldValueData
{
GENERATED_BODY()
public:
@ -151,7 +151,7 @@ public:
};
USTRUCT(Blueprintable)
struct FJSONFieldData
struct FBugzillaJSONFieldData
{
GENERATED_BODY()
public:
@ -164,16 +164,16 @@ public:
UPROPERTY(BlueprintReadOnly)
bool is_mandatory = false;
UPROPERTY(BlueprintReadOnly)
TArray<FJSONFieldValueData> values;
TArray<FBugzillaJSONFieldValueData> values;
};
USTRUCT(Blueprintable)
struct FJSONFieldResponse
struct FBugzillaJSONFieldResponse
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly)
TArray<FJSONFieldData> fields;
TArray<FBugzillaJSONFieldData> fields;
UPROPERTY(BlueprintReadOnly)
bool error = false;
@ -193,7 +193,7 @@ public:
* JSON structs for bug lists
*/
USTRUCT(Blueprintable)
struct FJSONBugData
struct FBugzillaJSONBugData
{
GENERATED_BODY()
public:
@ -224,12 +224,12 @@ public:
};
USTRUCT(Blueprintable)
struct FJSONBugResponse
struct FBugzillaJSONBugResponse
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly)
TArray<FJSONBugData> bugs;
TArray<FBugzillaJSONBugData> bugs;
UPROPERTY(BlueprintReadOnly)
bool error = false;
UPROPERTY(BlueprintReadOnly)

View File

@ -0,0 +1,7 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
//#include "JiraJSONStructs.generated.h"

Binary file not shown.

View File

@ -24,22 +24,21 @@ public:
UPROPERTY(Config, BlueprintReadOnly, EditDefaultsOnly, Category="Bug Placement", meta=(DisplayName="Arbitrary Placement Distance"))
float ArbitraryBugPlacementDistance = 250.0f;
// The status to use when filing a new bug. A status such as "UNCONFIRMED" is suggested.
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting")
FString DefaultStatus;
// The Bugzilla server where bugs will be posted.
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting")
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Bugzilla")
FString SubmissionServer;
// The name of the product for which bugs will be posted.
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting")
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Bugzilla")
FString ProductName;
// The API key to use when posting bugs. All bugs will be posted under the account of the owner of this API key.
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting", meta=(DisplayName="API Key"))
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Bugzilla", meta=(DisplayName="API Key"))
FString APIKey;
// The viewport depth of the bug report interface widget.
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting")
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Bugzilla")
int32 BugReportWidgetDepth = 0;
// The status to use when filing a new bug. A status such as "UNCONFIRMED" is suggested.
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting|Bugzilla")
FString DefaultStatus;
// Whether to show unresolved bugs when displaying bug report markers.
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Marking")