// Copyright (c) 2026 Reignance Studios. MIT License, see LICENSE. #pragma once #include "CoreMinimal.h" class UBlueprint; enum class ERSAuditSeverity : uint8 { Info, Warning, Error }; /** Which findings fail a CI run (commandlet exit code and JUnit failures). */ enum class ERSAuditFailOn : uint8 { Error, Warning, None }; /** One problem found by one check. */ struct RSNETAUDIT_API FRSAuditFinding { /** Stable id, e.g. GA-03. Listed in the README. */ FString CheckId; ERSAuditSeverity Severity = ERSAuditSeverity::Info; /** Class or asset path the finding is about. */ FString Subject; FString Message; FString Fix; /** Tutorial slug on reignancestudios.com that explains the fix. */ FString Tutorial; /** Matched a line in the ignore file. Suppressed findings are reported but never counted or failed. */ bool bSuppressed = false; FString SuppressReason; }; /** A table of what the audit read, for the report's inventory section. */ struct RSNETAUDIT_API FRSAuditTable { FString Title; TArray Columns; TArray> Rows; }; struct RSNETAUDIT_API FRSAuditOptions { /** Also scan engine and marketplace classes. Off by default: you cannot fix those. */ bool bIncludeEngineClasses = false; /** PlayerStates that hold an ASC below this rate get a warning. Lyra uses 100. */ float MinPlayerStateNetUpdateFrequency = 30.f; /** Bytes per second per client below which NET-01 warns. */ int32 MinClientRate = 30000; /** Severity that counts as failing in the JUnit report and the commandlet exit code. */ ERSAuditFailOn FailOn = ERSAuditFailOn::Error; /** Empty = /Config/RSNetAudit.ignore. */ FString IgnoreFile; /** Empty = /Saved/RSNetAudit. */ FString OutputDir; }; struct RSNETAUDIT_API FRSAuditResult { TArray Findings; TArray Inventory; int32 AbilitiesScanned = 0; int32 AbilityBlueprintsScanned = 0; int32 PlayerStatesScanned = 0; int32 AttributeSetsScanned = 0; FString IgnoreFile; FString MarkdownPath; FString HtmlPath; FString JsonPath; FString JUnitPath; /** Findings of this severity, not counting suppressed ones. */ int32 Count(ERSAuditSeverity Severity) const; int32 SuppressedCount() const; bool IsFailing(const FRSAuditFinding& Finding, ERSAuditFailOn FailOn) const; int32 FailingCount(ERSAuditFailOn FailOn) const; }; /** * Runs every check and writes the report. Editor only: it loads Blueprint * classes and reads their graphs. Safe to run from the commandlet, the * Tools menu or the RSNetAudit.Run console command. */ class RSNETAUDIT_API FRSNetAuditRunner { public: static FRSAuditResult Run(const FRSAuditOptions& Options); /** The Blueprint graph check (GA-05) on one ability Blueprint. Run calls it for every ability; tests call it directly. */ static TArray CheckAbilityGraphs(const UBlueprint* Blueprint); };