Files
UnrealEngine/Engine/Plugins/Online/OnlineFramework/Source/Qos/Private/QosStats.h
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

274 lines
6.4 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Serialization/JsonSerializerMacros.h"
#include "QosRegionManager.h"
class IAnalyticsProvider;
struct FDatacenterQosInstance;
/** Types of result determination types */
enum class EDatacenterResultType :uint8
{
/** Normal flow result */
Normal,
/** Using previously cached value */
Cached,
/** Using forced */
Forced,
/** Using forced default */
Default,
/** Failure to complete */
Failure
};
/** @return the stringified version of the enum passed in */
inline const TCHAR* ToString(EDatacenterResultType ResultType)
{
switch (ResultType)
{
case EDatacenterResultType::Normal:
{
return TEXT("Normal");
}
case EDatacenterResultType::Cached:
{
return TEXT("Cached");
}
case EDatacenterResultType::Forced:
{
return TEXT("Forced");
}
case EDatacenterResultType::Default:
{
return TEXT("Default");
}
case EDatacenterResultType::Failure:
{
return TEXT("Failure");
}
}
return TEXT("");
}
/**
* Datacenter determination stats
*/
class FQosDatacenterStats
{
private:
struct FQosStats_Timer
{
/** Time in ms captured */
double MSecs;
/** Is this timer running */
bool bInProgress;
FQosStats_Timer() :
MSecs(0.0),
bInProgress(false)
{}
};
class FQosStats_RegionInfo : public FJsonSerializable
{
public:
/** Region designation */
FString RegionId;
/** Parent region */
FString ParentRegionId;
/** Number of Qos servers pinged */
int32 NumResults;
/** Average ping across all results */
int32 AvgPing;
/** Is the region usable by the player */
bool bUsable;
FQosStats_RegionInfo()
: RegionId(TEXT("Unknown"))
, ParentRegionId(TEXT("Unknown"))
, NumResults(0)
, AvgPing(UNREACHABLE_PING)
, bUsable(false)
{}
BEGIN_JSON_SERIALIZER
JSON_SERIALIZE("RegionId", RegionId);
JSON_SERIALIZE("ParentRegionId", ParentRegionId);
JSON_SERIALIZE("bUsable", bUsable);
JSON_SERIALIZE("AvgPing", AvgPing);
JSON_SERIALIZE("NumResults", NumResults);
END_JSON_SERIALIZER
};
/** Stats representation of a single Qos search result */
struct FQosStats_QosSearchResult
{
/** Owner of the session */
FString OwnerId;
/** Datacenter Id */
FString DatacenterId;
/** Ping time */
int32 PingInMs;
/** Is this result valid */
bool bIsValid;
FQosStats_QosSearchResult() :
PingInMs(0),
bIsValid(false)
{}
};
struct FQosStats_CompletePass
{
/** Time of the search */
FString Timestamp;
/** Way the datacenter was chosen */
EDatacenterResultType DeterminationType;
/** Time in ms it took to find the search results (exclusive) */
FQosStats_Timer SearchTime;
/** Array of region information */
TArray<FQosStats_RegionInfo> Regions;
/** name for the region chosen based on rules */
FString RulesChosenRegion;
/** name for the sub region chosen based on rules */
FString RulesChosenSubRegion;
/** Number of search results tested */
int32 NumTotalSearches;
/** Number of successful search results */
int32 NumSuccessAttempts;
/** Array of search result details found this pass */
TArray<FQosStats_QosSearchResult> SearchResults;
FQosStats_CompletePass() :
DeterminationType(EDatacenterResultType::Failure),
NumTotalSearches(0),
NumSuccessAttempts(0)
{}
~FQosStats_CompletePass() {}
};
// Events
static const FString QosStats_DatacenterEvent;
// Common attribution
static const FString QosStats_SessionId;
static const FString QosStats_Version;
// Header stats
static const FString QosStats_Timestamp;
static const FString QosStats_TotalTime;
// Qos stats
static const FString QosStats_DeterminationType;
static const FString QosStats_NumRegions;
static const FString QosStats_RegionDetails;
static const FString QosStats_NumResults;
static const FString QosStats_NumSuccessCount;
static const FString QosStats_NetworkType;
static const FString QosStats_BestRegionId;
static const FString QosStats_BestRegionPing;
static const FString QosStats_BestEndpointId;
static const FString QosStats_BestEndpointPing;
static const FString QosStats_ChosenRegionId;
static const FString QosStats_ChosenSubRegionId;
static const FString QosStats_ChosenSubRegionPing;
/** Version of the stats for separation */
int32 StatsVersion;
/** Container of an entire search process */
FQosStats_CompletePass QosData;
/** Analytics in progress */
bool bAnalyticsInProgress;
/**
* Start the timer for a given stats container
*
* @param Timer Timer to start
*/
void StartTimer(FQosStats_Timer& Timer);
/**
* Stops the timer for a given stats container
*
* @param Timer Timer to stop
*/
void StopTimer(FQosStats_Timer& Timer);
/**
* Finalize all the data, stopping timers, etc
*/
void Finalize();
/**
* Parse an entire search, adding its data to the recorded event
*
* @param AnalyticsProvider provider recording the event
* @param SessionId unique id for the qos event
*/
void ParseQosResults(TSharedPtr<IAnalyticsProvider>& AnalyticsProvider, FGuid& SessionId);
public:
FQosDatacenterStats();
virtual ~FQosDatacenterStats() {}
/**
* Start a Qos search pass
*/
void StartQosPass();
/**
* Record a new region
*
* @param RegionInfo info obtained about a region
* @param NumResults num results considered
*/
void RecordRegionInfo(const FDatacenterQosInstance& RegionInfo, int32 NumResults);
/**
* Record a single ping attempt
*
* @param Region region of the server
* @param OwnerId the owner of the server (ip address)
* @param PingInMs ping to the server
* @param bSuccess was the attempt successful
*/
void RecordQosAttempt(const FString& Region, const FString& OwnerId, int32 PingInMs, bool bSuccess);
/**
* End recording of a Qos determination
*
* @param Result results of the qos pass
*/
void EndQosPass(EDatacenterResultType Result);
/**
* Set the chosen region from Qos Evaluation (may differ from the fastest/best based on rules)
*
* @param Region string region code of chosen region
*/
void SetChosenRegion(FString&& Region);
/**
* Set the chosen SubRegion from Qos Evaluation (may differ from the fastest/best based on rules)
*
* @param Region string SubRegion code of chosen region
*/
void SetChosenSubRegion(FString && SubRegion);
/**
* Record previously saved stats to an analytics provider
*
* @param AnalyticsProvider provider to record stats to
*/
void Upload(TSharedPtr<IAnalyticsProvider>& AnalyticsProvider);
};