Skip to content

Input email #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: dev
Choose a base branch
from
Open
8 changes: 7 additions & 1 deletion BetaHubBugReporter.uplugin
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"Description": "Bug reporting functionality for BetaHub.io",
"Category": "Other",
"CreatedBy": "Upsoft sp. z o. o.",
"EngineVersion": "5.3.0",
"EngineVersion": [ "5.3.0", "5.4.0", "5.5.0" ],
"CreatedByURL": "https://betahub.io/",
"DocsURL": "https://www.betahub.io/docs/integration-guides/#unreal-plugin-integration",
"MarketplaceURL": "",
Expand All @@ -25,6 +25,12 @@
]
}
],
"Plugins": [
{
"Name": "EnhancedInput",
"Enabled": true
}
],
"AdditionalFiles": [
"ThirdParty/FFmpeg/Windows/ffmpeg.exe"
]
Expand Down
Binary file modified Content/BugReportForm.uasset
Binary file not shown.
1 change: 1 addition & 0 deletions Source/BetaHubBugReporter/BetaHubBugReporter.Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public BetaHubBugReporter(ReadOnlyTargetRules Target) : base(Target)
"JsonUtilities",
"RenderCore",
"RHI",
"EnhancedInput"
// ... add private dependencies that you statically link with here ...
}
);
Expand Down
8 changes: 6 additions & 2 deletions Source/BetaHubBugReporter/Private/BH_BugReport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ void UBH_BugReport::SubmitReport(
UBH_GameRecorder* GameRecorder,
const FString& Description,
const FString& StepsToReproduce,
const FString& UserEmail,
const FString& ScreenshotPath,
const FString& LogFileContents,
bool bIncludeVideo,
Expand All @@ -35,11 +36,11 @@ void UBH_BugReport::SubmitReport(
{
Async(EAsyncExecution::Thread,
[this,
Settings, GameRecorder, Description, StepsToReproduce, ScreenshotPath, LogFileContents,
Settings, GameRecorder, Description, StepsToReproduce, UserEmail, ScreenshotPath, LogFileContents,
bIncludeVideo, bIncludeLogs, bIncludeScreenshot,
OnSuccess, OnFailure]()
{
SubmitReportAsync(Settings, GameRecorder, Description, StepsToReproduce, ScreenshotPath, LogFileContents,
SubmitReportAsync(Settings, GameRecorder, Description, StepsToReproduce, UserEmail, ScreenshotPath, LogFileContents,
bIncludeVideo, bIncludeLogs, bIncludeScreenshot,
OnSuccess, OnFailure);
});
Expand All @@ -50,6 +51,7 @@ void UBH_BugReport::SubmitReportAsync(
UBH_GameRecorder* GameRecorder,
const FString& Description,
const FString& StepsToReproduce,
const FString& UserEmail,
const FString& ScreenshotPath,
const FString& LogFileContents,
bool bIncludeVideo,
Expand All @@ -74,6 +76,8 @@ void UBH_BugReport::SubmitReportAsync(
InitialRequest->SetHeader(TEXT("Accept"), TEXT("application/json"));
InitialRequest->AddField(TEXT("issue[description]"), Description);
InitialRequest->AddField(TEXT("issue[unformatted_steps_to_reproduce]"), StepsToReproduce);
//TODO enable adding user email as field when endpoint allows it
//InitialRequest->AddField(TEXT("issue[user_email]"), UserEmail);
InitialRequest->FinalizeFormData();

InitialRequest->ProcessRequest(
Expand Down
15 changes: 15 additions & 0 deletions Source/BetaHubBugReporter/Private/BH_GameInstanceSubsystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,19 @@ void UBH_GameInstanceSubsystem::Deinitialize()
{
Manager->StopService();
}
}

void UBH_GameInstanceSubsystem::HideScreenAreaFromReport(FVector4 AreaToHide)
{
Manager->HideScreenAreaFromReport(AreaToHide);
}

void UBH_GameInstanceSubsystem::HideScreenAreaFromReportArray(TArray<FVector4> AreasToHide)
{
Manager->HideScreenAreaFromReportArray(AreasToHide);
}

void UBH_GameInstanceSubsystem::SetHiddenAreaColor(FLinearColor NewColor)
{
Manager->SetHiddenAreaColor(NewColor.ToFColor(false));
}
98 changes: 92 additions & 6 deletions Source/BetaHubBugReporter/Private/BH_GameRecorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ UBH_GameRecorder::UBH_GameRecorder(const FObjectInitializer& ObjectInitializer)
, ViewportHeight(0)
, FrameWidth(0)
, FrameHeight(0)
, RawFrameBufferPool(3)
, HiddenAreaColor(FColor::Black)
, LastCaptureTime(0)
, RawFrameBufferQueue()
, RawFrameBufferPool(3)
, MainEditorWindow(nullptr)
, LargestSize(0, 0)
, MaxVideoWidth(512) // Initialize with minimum value
Expand Down Expand Up @@ -193,6 +194,18 @@ void UBH_GameRecorder::Tick(float DeltaTime)
{
PendingPixels[i] = PendingLinearPixels[i].ToFColor(false);
}

TArray<int32> HiddenIdices;

for (FVector4 DisabledRect : HiddenAreas)
{
HiddenIdices.Append(GetPixelIndicesFromViewportRectangle(FVector2D(DisabledRect.X, DisabledRect.Y), FVector2D(DisabledRect.Z, DisabledRect.W), TextureBuffer->GetWidth(), TextureBuffer->GetHeight()));
}

for (int32 Index : HiddenIdices)
{
PendingPixels[Index] = HiddenAreaColor;
}

// Resize image to frame
ResizeImageToFrame(PendingPixels, TextureBuffer->GetWidth(), TextureBuffer->GetHeight(), FrameWidth, FrameHeight, ResizedPixels);
Expand Down Expand Up @@ -235,6 +248,56 @@ void UBH_GameRecorder::ResizeImageToFrame(
}
}

TArray<int32> UBH_GameRecorder::GetPixelIndicesFromViewportRectangle(const FVector2D& TopLeftViewportCoords, const FVector2D& BottomRightViewportCoords, int32 TextureWidth, int32 TextureHeight)
{
TArray<int32> PixelIndices;

// Get viewport size
FVector2D ViewportSize;
GEngine->GameViewport->GetViewportSize(ViewportSize);

// Check if viewport size and texture size are valid
if (ViewportSize.X <= 0 || ViewportSize.Y <= 0 || TextureWidth <= 0 || TextureHeight <= 0)
{
return PixelIndices; // Return empty if sizes are invalid
}

// Normalize the viewport coordinates (0 to 1)
float NormalizedTopLeftX = TopLeftViewportCoords.X / ViewportSize.X;
float NormalizedTopLeftY = TopLeftViewportCoords.Y / ViewportSize.Y;
float NormalizedBottomRightX = BottomRightViewportCoords.X / ViewportSize.X;
float NormalizedBottomRightY = BottomRightViewportCoords.Y / ViewportSize.Y;

// Convert normalized coordinates to texture coordinates
int32 TextureX1 = FMath::Clamp(static_cast<int32>(NormalizedTopLeftX * TextureWidth), 0, TextureWidth - 1);
int32 TextureY1 = FMath::Clamp(static_cast<int32>(NormalizedTopLeftY * TextureHeight), 0, TextureHeight - 1);
int32 TextureX2 = FMath::Clamp(static_cast<int32>(NormalizedBottomRightX * TextureWidth), 0, TextureWidth - 1);
int32 TextureY2 = FMath::Clamp(static_cast<int32>(NormalizedBottomRightY * TextureHeight), 0, TextureHeight - 1);

// Ensure coordinates are properly ordered (Top-left and bottom-right)
int32 StartX = FMath::Min(TextureX1, TextureX2);
int32 EndX = FMath::Max(TextureX1, TextureX2);
int32 StartY = FMath::Min(TextureY1, TextureY2);
int32 EndY = FMath::Max(TextureY1, TextureY2);

// Iterate through the rectangle area to collect indices
for (int32 Y = StartY; Y <= EndY; ++Y)
{
for (int32 X = StartX; X <= EndX; ++X)
{
int32 PixelIndex = Y * TextureWidth + X;

// Check if the pixel index is within the bounds of the array
if (PixelIndex >= 0 && PixelIndex < PendingPixels.Num())
{
PixelIndices.Add(PixelIndex);
}
}
}

return PixelIndices;
}

bool UBH_GameRecorder::IsTickable() const
{
return bIsRecording;
Expand All @@ -245,7 +308,7 @@ TStatId UBH_GameRecorder::GetStatId() const
RETURN_QUICK_DECLARE_CYCLE_STAT(UBH_GameRecorder, STATGROUP_Tickables);
}

void UBH_GameRecorder::OnBackBufferReady(SWindow& Window, const FTexture2DRHIRef& BackBuffer)
void UBH_GameRecorder::OnBackBufferReady(SWindow& Window, const FTextureRHIRef& BackBuffer)
{
#if WITH_EDITOR
// Log window title and size for debugging
Expand Down Expand Up @@ -293,7 +356,7 @@ void UBH_GameRecorder::OnBackBufferReady(SWindow& Window, const FTexture2DRHIRef
{
FViewport* Viewport = GEngine->GameViewport->GetGameViewport();

FTexture2DRHIRef GameBuffer = BackBuffer;
FTextureRHIRef GameBuffer = BackBuffer;
if (!GameBuffer)
{
UE_LOG(LogBetaHub, Error, TEXT("Failed to get game buffer. Will try next time..."));
Expand Down Expand Up @@ -331,11 +394,18 @@ void UBH_GameRecorder::OnBackBufferReady(SWindow& Window, const FTexture2DRHIRef

if (!bCopyTextureStarted && StagingTexture != nullptr)
{
#if ENGINE_MINOR_VERSION >= 5
AsyncTask(ENamedThreads::GameThread, [this, BackBuffer]()
{
ReadPixels(BackBuffer);
});
#else
ReadPixels(BackBuffer);
#endif
}
}

void UBH_GameRecorder::ReadPixels(const FTexture2DRHIRef& BackBuffer)
void UBH_GameRecorder::ReadPixels(const FTextureRHIRef& BackBuffer)
{
if (!GEngine || !GEngine->GameViewport) return;

Expand Down Expand Up @@ -364,7 +434,7 @@ void UBH_GameRecorder::ReadPixels(const FTexture2DRHIRef& BackBuffer)
return;
}

FTexture2DRHIRef Texture = BackBuffer;
FTextureRHIRef Texture = BackBuffer;

FRHICopyTextureInfo CopyInfo;
RHICmdList.CopyTexture(Texture, StagingTexture, CopyInfo);
Expand All @@ -386,14 +456,15 @@ void UBH_GameRecorder::ReadPixels(const FTexture2DRHIRef& BackBuffer)
RawFrameBufferQueue.Enqueue(TextureBuffer);

RHICmdList.UnmapStagingSurface(StagingTexture);

}
);

CopyTextureFence.BeginFence();
bCopyTextureStarted = true;
}

void UBH_GameRecorder::OnBackBufferResized(const FTexture2DRHIRef& BackBuffer)
void UBH_GameRecorder::OnBackBufferResized(const FTextureRHIRef& BackBuffer)
{
FIntVector OriginalSize = BackBuffer->GetDesc().GetSize();

Expand Down Expand Up @@ -481,6 +552,21 @@ void UBH_GameRecorder::SetMaxVideoDimensions(int32 InMaxWidth, int32 InMaxHeight
MaxVideoHeight = FMath::Max(InMaxHeight, 512);
}

void UBH_GameRecorder::HideScreenAreaFromReport(FVector4 AreaToHide)
{
HiddenAreas.Add(AreaToHide);
}

void UBH_GameRecorder::HideScreenAreaFromReportArray(TArray<FVector4> AreasToHide)
{
HiddenAreas.Append(AreasToHide);
}

void UBH_GameRecorder::SetHiddenAreaColor(FColor NewColor)
{
HiddenAreaColor = NewColor;
}

#if ENGINE_MINOR_VERSION < 4
bool ConvertRAWSurfaceDataToFLinearColor(EPixelFormat Format, uint32 Width, uint32 Height, uint8 *In, uint32 SrcPitch, FLinearColor* Out, FReadSurfaceDataFlags InFlags)
{
Expand Down
15 changes: 12 additions & 3 deletions Source/BetaHubBugReporter/Private/BH_GameRecorder.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class BETAHUBBUGREPORTER_API UBH_GameRecorder : public UObject, public FTickable
virtual bool IsTickable() const override;
virtual TStatId GetStatId() const override;

void HideScreenAreaFromReport(FVector4 AreaToHide);
void HideScreenAreaFromReportArray(TArray<FVector4> AreasToHide);
void SetHiddenAreaColor(FColor NewColor);

// Sets the maximum video dimensions while maintaining aspect ratio
void SetMaxVideoDimensions(int32 InMaxWidth, int32 InMaxHeight);

Expand All @@ -48,6 +52,9 @@ class BETAHUBBUGREPORTER_API UBH_GameRecorder : public UObject, public FTickable
UPROPERTY()
ABH_SceneCaptureActor* SceneCaptureActor;

TArray<FVector4> HiddenAreas;
FColor HiddenAreaColor;

TSharedPtr<BH_VideoEncoder> VideoEncoder;
int32 TargetFPS;
FTimespan RecordingDuration;
Expand All @@ -61,7 +68,7 @@ class BETAHUBBUGREPORTER_API UBH_GameRecorder : public UObject, public FTickable
TArray<FColor> PendingPixels;
TArray<FColor> ResizedPixels;

FTexture2DRHIRef StagingTexture;
FTextureRHIRef StagingTexture;
EPixelFormat StagingTextureFormat;

int32 ViewportWidth;
Expand All @@ -85,9 +92,11 @@ class BETAHUBBUGREPORTER_API UBH_GameRecorder : public UObject, public FTickable
void SetFrameData(int32 Width, int32 Height, const TArray<FColor>& Data);
void ResizeImageToFrame(const TArray<FColor>& ImageData, uint32 ImageWidth, uint32 ImageHeight, uint32 FrameWidth, uint32 FrameHeight, TArray<FColor>& ResizedData);

void OnBackBufferReady(SWindow& Window, const FTexture2DRHIRef& BackBuffer);
TArray<int32> GetPixelIndicesFromViewportRectangle(const FVector2D& TopLeftViewportCoords, const FVector2D& BottomRightViewportCoords, int32 TextureWidth, int32 TextureHeight);

void OnBackBufferReady(SWindow& Window, const FTextureRHIRef& BackBuffer);

void OnBackBufferResized(const FTexture2DRHIRef& BackBuffer);
void OnBackBufferResized(const FTextureRHIRef& BackBuffer);

//Hack TODO
TSet<FString> CreatedWindows;
Expand Down
43 changes: 37 additions & 6 deletions Source/BetaHubBugReporter/Private/BH_Manager.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "BH_Manager.h"
#include "BH_Log.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "InputMappingContext.h"
#include "HttpModule.h"
#include "Engine/GameInstance.h"
#include "Interfaces/IHttpRequest.h"
Expand All @@ -12,6 +15,13 @@ UBH_Manager::UBH_Manager()
: InputComponent(nullptr)
{
Settings = GetMutableDefault<UBH_PluginSettings>();

IA_ShowReportForm = GetMutableDefault<UInputAction>();
IA_ShowReportForm->bTriggerWhenPaused = true;
IA_ShowReportForm->bReserveAllMappings = true;
BetaHubMappingContext = GetMutableDefault<UInputMappingContext>();

BetaHubMappingContext->MapKey(IA_ShowReportForm, Settings->ShortcutKey);
}

void UBH_Manager::StartService(UGameInstance* GI)
Expand Down Expand Up @@ -97,15 +107,36 @@ void UBH_Manager::OnPlayerControllerChanged(APlayerController* PC)
{
CurrentPlayerController = PC;

if (PC)
//Add Input Mapping Context
UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer());

if (Subsystem && BetaHubMappingContext)
{
Subsystem->AddMappingContext(BetaHubMappingContext, 0);
}

if (PC && IA_ShowReportForm)
{
InputComponent = NewObject<UInputComponent>(PC);
InputComponent->RegisterComponent();
InputComponent->BindKey(Settings->ShortcutKey, IE_Pressed, this, &UBH_Manager::OnBackgroundServiceRequestWidget);
PC->PushInputComponent(InputComponent);
InputComponent = Cast<UEnhancedInputComponent>(PC->InputComponent);
InputComponent->BindAction(IA_ShowReportForm, ETriggerEvent::Completed, this, &UBH_Manager::OnBackgroundServiceRequestWidget);
}
}

void UBH_Manager::HideScreenAreaFromReport(FVector4 AreaToHide)
{
BackgroundService->GetGameRecorder()->HideScreenAreaFromReport(AreaToHide);
}

void UBH_Manager::HideScreenAreaFromReportArray(TArray<FVector4> AreasToHide)
{
BackgroundService->GetGameRecorder()->HideScreenAreaFromReportArray(AreasToHide);
}

void UBH_Manager::SetHiddenAreaColor(FColor NewColor)
{
BackgroundService->GetGameRecorder()->SetHiddenAreaColor(NewColor);
}

void UBH_Manager::FetchAllReleases()
{
if (!Settings)
Expand Down Expand Up @@ -301,4 +332,4 @@ void UBH_Manager::OnFetchReleaseByIdResponse(FHttpRequestPtr Request, FHttpRespo
{
UE_LOG(LogBetaHub, Error, TEXT("Invalid JSON response for release by ID. Check your endpoint, your project ID and if the project is not set to private."));
}
}
}
4 changes: 2 additions & 2 deletions Source/BetaHubBugReporter/Private/BH_PopupWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

#include "BH_PopupWidget.h"

void UBH_PopupWidget::NativeConstruct()
void UBH_PopupWidget::NativeOnInitialized()
{
Super::NativeConstruct();
Super::NativeOnInitialized();

if (this->CloseButton)
{
Expand Down
Loading