Bug submission works, and now there is a mysterious bug that makes this whole thing crash for reasons I am unable to track. Great.

This commit is contained in:
Jamie Greunbaum 2023-03-24 01:44:40 -04:00
parent 5abc7ca484
commit 32d0d61e67
14 changed files with 201 additions and 94 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

View File

@ -44,12 +44,23 @@ const FString FormatQueryString(const TMap<FString, FString> &QueryData)
return FString::Join(AssembledKeyValuePairs, TEXT("&"));
}
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::FromString(GetDefault<UUnrealzillaGlobalSettings>()->ProductName));
this->ProductNameValue->SetText(FText::AsCultureInvariant(GetDefault<UUnrealzillaGlobalSettings>()->ProductName));
const FString FullURL = GetDefault<UUnrealzillaGlobalSettings>()->SubmissionServer + "/rest.cgi";
@ -100,7 +111,7 @@ void UBugSubmissionForm::SetMarkerData(ABugMarkerActor *BugMarker)
{
this->BugMarkerActor = BugMarker;
MapNameValue->SetText(FText::FromString(this->GetWorld()->GetMapName().RightChop(this->GetWorld()->StreamingLevelsPrefix.Len())));
this->MapName = FText::AsCultureInvariant(this->GetWorld()->GetMapName().RightChop(this->GetWorld()->StreamingLevelsPrefix.Len()));
const FVector MarkerLocation = this->BugMarkerActor->GetActorLocation();
FFormatNamedArguments MarkerLocationArgs;
@ -121,13 +132,13 @@ void UBugSubmissionForm::SetMarkerData(ABugMarkerActor *BugMarker)
MapDataArgs.Add("MarkerUpVector", MarkerUpVectorText);
const FText MapDataText = FText::Format(NSLOCTEXT("BugSubmissionForm", "MapDataFormat", "{MarkerLocation}:{MarkerUpVector}"), MapDataArgs);
this->LocationValue->SetText(MapDataText);
this->MarkerLocation = MapDataText;
}
void UBugSubmissionForm::ShowProcessingOverlayLoading()
{
this->ProcessingRequestErrorText->SetText(FText::FromString(""));
this->ProcessingRequestErrorText->SetText(FText::AsCultureInvariant(""));
this->ProcessingRequestOverlay->SetVisibility(ESlateVisibility::Visible);
this->ProcessingRequestThrobber->SetVisibility(ESlateVisibility::Visible);
this->ProcessingRequestErrorBox->SetVisibility(ESlateVisibility::Collapsed);
@ -135,7 +146,7 @@ void UBugSubmissionForm::ShowProcessingOverlayLoading()
void UBugSubmissionForm::ShowProcessingOverlayMessage(const FString Message)
{
this->ProcessingRequestErrorText->SetText(FText::FromString(Message));
this->ProcessingRequestErrorText->SetText(FText::AsCultureInvariant(Message));
this->ProcessingRequestOverlay->SetVisibility(ESlateVisibility::Visible);
this->ProcessingRequestThrobber->SetVisibility(ESlateVisibility::Collapsed);
this->ProcessingRequestErrorBox->SetVisibility(ESlateVisibility::Visible);
@ -160,27 +171,52 @@ void UBugSubmissionForm::SubmitForm()
const FString SummaryText = this->SummaryEntryBox->GetText().ToString();
const FString CommentText = this->CommentEntryBox->GetText().ToString();
if (SummaryText.IsEmpty())
{
this->ShowProcessingOverlayMessage("You must provide a summary.");
}
//if (CommentText.IsEmpty())
//{
// this->ShowProcessingOverlayMessage("You must provide a description.");
//}
const FString DefaultStatus = GetDefault<UUnrealzillaGlobalSettings>()->DefaultStatus;
FString PostJsonString;
FJSONPostBug PostData;
PostData.product = GetDefault<UUnrealzillaGlobalSettings>()->ProductName;
PostData.component = "Component";
PostData.version = "unspecified";
PostData.cf_mapname = this->MapNameValue->GetText().ToString();
PostData.cf_location = this->LocationValue->GetText().ToString();
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"));
@ -247,8 +283,9 @@ void UBugSubmissionForm::ServerProductInfoResponse(FHttpRequestPtr Request, FHtt
}
else
{
for (const FJSONProductData &ProductData : ResponseData.products)
if (!ResponseData.products.IsEmpty())
{
const FJSONProductData &ProductData = ResponseData.products[0];
if (ProductData.name == GetDefault<UUnrealzillaGlobalSettings>()->ProductName)
{
for (const FJSONComponentData &ComponentData : ProductData.components)
@ -259,10 +296,26 @@ void UBugSubmissionForm::ServerProductInfoResponse(FHttpRequestPtr Request, FHtt
{
this->VersionsList.Add(VersionData.name);
}
break;
}
}
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();
}
}
@ -370,50 +423,41 @@ void UBugSubmissionForm::CheckIfAllInitialResponsesAreIn()
if (!this->ComponentList.IsEmpty() && !this->VersionsList.IsEmpty() && !this->SeverityList.IsEmpty() &&
!this->PlatformsList.IsEmpty() && !this->OSList.IsEmpty())
{
if (this->PlatformsList.Contains("PC"))
// 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->ShowProcessingOverlayMessage("Windows detected");
this->HardwareButton->SetText(FText::AsCultureInvariant("PC"));
this->OSButton->SetText(FText::AsCultureInvariant("Windows"));
}
else if (UGameplayStatics::GetPlatformName() == "Linux" && this->OSList.Contains("Linux"))
{
this->ShowProcessingOverlayMessage("Linux on PC detected");
this->HardwareButton->SetText(FText::AsCultureInvariant("PC"));
this->OSButton->SetText(FText::AsCultureInvariant("Linux"));
}
else if (UGameplayStatics::GetPlatformName() == "Mac" && this->OSList.Contains("Mac OS"))
{
this->ShowProcessingOverlayMessage("This should not be possible");
}
else
{
this->ShowProcessingOverlayMessage("Could not auto-detect operating system");
this->HardwareButton->SetText(FText::AsCultureInvariant("All"));
this->OSButton->SetText(FText::AsCultureInvariant("Mac OS"));
}
}
else if (this->PlatformsList.Contains("Macintosh"))
if (UGameplayStatics::GetPlatformName() == "Mac") // Try our best to auto-detect Macintosh hardware
{
if (UGameplayStatics::GetPlatformName() == "Windows" && this->OSList.Contains("Windows"))
if (this->PlatformsList.Contains("Macintosh"))
{
this->ShowProcessingOverlayMessage("Windows on a Macintosh detected");
if (this->OSList.Contains("Mac OS"))
{
this->HardwareButton->SetText(FText::AsCultureInvariant("Macintosh"));
this->OSButton->SetText(FText::AsCultureInvariant("Mac OS"));
}
}
else if (UGameplayStatics::GetPlatformName() == "Linux" && this->OSList.Contains("Linux"))
{
this->ShowProcessingOverlayMessage("Linux on a Macintosh detected");
}
else if (UGameplayStatics::GetPlatformName() == "Mac" && this->OSList.Contains("Mac OS"))
{
this->ShowProcessingOverlayMessage("macOS detected");
}
else
{
this->ShowProcessingOverlayMessage("Could not auto-detect operating system");
}
}
else // At this stage, don't bother trying to auto-detect; we'll just set it to All here.
{
this->ShowProcessingOverlayMessage("Can't auto-detect platform");
}
//this->HideProcessingOverlay();
this->HideProcessingOverlay();
}
}

View File

@ -0,0 +1,36 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "CommonButtonBase.h"
#include "CommonTextBlock.h"
#include "BugFormButton.generated.h"
UCLASS()
class UNREALZILLA_API UBugFormButton : public UCommonButtonBase
{
GENERATED_BODY()
public:
virtual void NativeConstruct() override { this->SetText(this->CurrentText); }
UFUNCTION(BlueprintCallable)
void SetText(const FText Text) { this->CurrentText = Text.IsEmpty() ? this->DefaultText : Text; this->TextLabel->SetText(this->CurrentText); }
UFUNCTION(BlueprintPure)
FText GetText() const { return this->TextLabel->GetText().EqualTo(this->DefaultText) ? FText::GetEmpty() : this->TextLabel->GetText(); }
protected:
virtual void NativePreConstruct() override { this->TextLabel->SetText(this->DefaultText); }
UPROPERTY(BlueprintReadOnly, meta=(BindWidget))
TObjectPtr<class UCommonTextBlock> TextLabel;
UPROPERTY(BlueprintReadOnly, EditAnywhere)
FText DefaultText;
private:
FText CurrentText;
};

View File

@ -1,26 +0,0 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "CommonButtonBase.h"
#include "CommonTextBlock.h"
#include "BugFormTextEntryButton.generated.h"
UCLASS()
class UNREALZILLA_API UBugFormTextEntryButton : public UCommonButtonBase
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
void SetText(const FText Text) { this->TextLabel->SetText(Text); }
UFUNCTION(BlueprintPure)
FText GetText() const { return this->TextLabel->GetText(); }
protected:
UPROPERTY(BlueprintReadOnly, meta=(BindWidget))
TObjectPtr<class UCommonTextBlock> TextLabel;
};

View File

@ -4,7 +4,7 @@
#include "CoreMinimal.h"
#include "BugFormTextEntryButton.h"
#include "BugFormButton.h"
#include "CommonActivatableWidget.h"
#include "Interfaces/IHttpRequest.h"
#include "Interfaces/IHttpResponse.h"
@ -22,22 +22,26 @@ struct FJSONPostBug
public:
UPROPERTY()
FString product;
UPROPERTY()
FString component;
UPROPERTY()
FString version;
UPROPERTY()
FString cf_mapname;
UPROPERTY()
FString cf_location;
UPROPERTY()
FString platform;
UPROPERTY()
FString op_sys;
UPROPERTY()
FString component;
UPROPERTY()
FString severity;
UPROPERTY()
FString cf_mapname;
UPROPERTY()
FString cf_location;
UPROPERTY()
FString summary;
UPROPERTY()
FString description;
UPROPERTY()
FString status;
};
USTRUCT(Blueprintable)
@ -248,14 +252,22 @@ protected:
UPROPERTY(BlueprintReadOnly, meta=(BindWidget))
TObjectPtr<class UCommonTextBlock> ProductNameValue;
UPROPERTY(BlueprintReadOnly, meta=(BindWidget))
TObjectPtr<class UCommonTextBlock> MapNameValue;
TObjectPtr<class UBugFormButton> ComponentButton;
UPROPERTY(BlueprintReadOnly, meta=(BindWidget))
TObjectPtr<class UCommonTextBlock> LocationValue;
TObjectPtr<class UBugFormButton> VersionButton;
UPROPERTY(BlueprintReadOnly, meta=(BindWidget))
TObjectPtr<class UBugFormTextEntryButton> SummaryEntryBox;
TObjectPtr<class UBugFormButton> SeverityButton;
UPROPERTY(BlueprintReadOnly, meta=(BindWidget))
TObjectPtr<class UBugFormTextEntryButton> CommentEntryBox;
TObjectPtr<class UBugFormButton> HardwareButton;
UPROPERTY(BlueprintReadOnly, meta=(BindWidget))
TObjectPtr<class UBugFormButton> OSButton;
UPROPERTY(BlueprintReadOnly, meta=(BindWidget))
TObjectPtr<class UBugFormButton> SummaryEntryBox;
UPROPERTY(BlueprintReadOnly, meta=(BindWidget))
TObjectPtr<class UBugFormButton> CommentEntryBox;
UPROPERTY(BlueprintReadOnly, meta=(BindWidget))
TObjectPtr<class UCommonButtonBase> CancelButton;
@ -271,6 +283,17 @@ protected:
UPROPERTY(BlueprintReadOnly, meta=(BindWidget))
TObjectPtr<class UCommonTextBlock> ProcessingRequestErrorText;
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 ServerProductInfoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool Success);
@ -295,11 +318,8 @@ private:
void ServerConnectionError(const EHttpRequestStatus::Type Status);
TArray<FString> ComponentList;
TArray<FString> VersionsList;
TArray<FString> SeverityList;
TArray<FString> PlatformsList;
TArray<FString> OSList;
FText MapName;
FText MarkerLocation;
TObjectPtr<class ABugMarkerActor> BugMarkerActor;
};

View File

@ -8,28 +8,61 @@
/**
* Global settings for Unrealzilla classes
*/
* Global settings for Unrealzilla classes
*/
UCLASS(Config=Unrealzilla, defaultconfig, meta=(DisplayName="Unrealzilla"))
class UNREALZILLA_API UUnrealzillaGlobalSettings : public UDeveloperSettingsBackedByCVars
{
GENERATED_BODY()
public:
// The distance to send the trace out when placing bug markers in the world.
UPROPERTY(Config, BlueprintReadOnly, EditDefaultsOnly, Category="Bug Placement", meta=(DisplayName="Precise Placement Distance"))
float BugPlacementTraceDistance = 1500.0f;
// The distance to hold the bug marker when using the arbitrary placement option.
UPROPERTY(Config, BlueprintReadOnly, EditDefaultsOnly, Category="Bug Placement", meta=(DisplayName="Arbitrary Placement Distance"))
float ArbitraryBugPlacementDistance = 250.0f;
// The Bugzilla server where bugs will be posted.
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting")
FString SubmissionServer;
// The name of the product for which bugs will be posted.
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting")
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"))
FString APIKey;
// The viewport depth of the bug report interface widget.
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Reporting")
int32 BugReportWidgetDepth = 0;
// The status to use when filing a new bug. A status such as "UNCONFIRMED" is suggested.
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Marking")
FString DefaultStatus;
// Whether to show unresolved bugs when displaying bug report markers.
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Marking")
bool bShowUnresolvedBugs = false;
// Whether to show in-progress bugs when displaying bug report markers.
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Marking")
bool bShowInProgressBugs = false;
// Whether to show resolved bugs when displaying bug report markers.
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Marking")
bool bShowResolvedBugs = false;
// A list of bug statuses that represent unresolved bugs in your Bugzilla install.
// Generally this would be something like "UNCONFIRMED" and "CONFIRMED".
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Marking")
TArray<FString> UnresolvedStatuses;
// A list of bug statuses that represent in progress bugs in your Bugzilla install.
// Generally this would include "IN_PROGRESS".
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Marking")
TArray<FString> InProgressStatuses;
// A list of bug statuses that represent resolved bugs in your Bugzilla install.
// Generally this would include "RESOLVED" and "VERIFIED".
UPROPERTY(Config, EditDefaultsOnly, BlueprintReadOnly, Category="Marking")
TArray<FString> ResolvedStatuses;
public:
virtual void PostInitProperties() override;
virtual FName GetCategoryName() const override;