Handle reports and sanctions
Submit player reports and respond to moderation outcomes.
Keep the reported player’s full handle. Reports and sanctions go to the provider that owns that handle; support is not shared across every platform.
Report a player
Loading the interactive viewer.
Game module dependencies: UCIKCore, BetideCore.
#include "Engine/GameInstance.h"
#include "Platform/UCIKPlatformSubsystem.h"
#include "UCIKCore.h"
void ReportPlayer(UGameInstance &GameInstance, const FUCIK_PlayerHandle &Player,
const FString &Reason, const FString &MatchId)
{
auto *Service = GameInstance.GetSubsystem<UUCIKPlatformSubsystem>();
if (!Service)
return;
FUCIK_PlayerReport Report;
Report.Player = Player;
Report.Category = EUCIK_ReportCategory::Cheating;
Report.Message = Reason;
Report.Context.Add(TEXT("MatchId"), MatchId);
Service->SendPlayerReport(
Report,
FBetideCallback<bool>::CreateWeakLambda(&GameInstance, [](const TBetideResult<bool> &Result) {
if (!Result.bOk)
{
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
return;
}
UE_LOG(LogUCIK, Log, TEXT("Report submitted: %d"), Result.GetValue());
}));
}Attach useful match details in Context. A submitted report is not a ban. Query sanctions separately and let your server decide how each action affects access.
Check active sanctions
List player sanctions
Loading the interactive viewer.
Check active sanctions
Loading the interactive viewer.
Game module dependencies: UCIKCore, BetideCore.
#include "Engine/GameInstance.h"
#include "Platform/UCIKPlatformSubsystem.h"
#include "UCIKCore.h"
void CheckPlayerSanctions(UGameInstance &GameInstance, const FUCIK_PlayerHandle &Player)
{
auto *Service = GameInstance.GetSubsystem<UUCIKPlatformSubsystem>();
if (!Service)
return;
Service->IsPlayerSanctioned(
Player,
FBetideCallback<bool>::CreateWeakLambda(&GameInstance, [](const TBetideResult<bool> &Result) {
if (!Result.bOk)
{
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
return;
}
UE_LOG(LogUCIK, Log, TEXT("Has active sanction: %d"), Result.GetValue());
}));
}void ListPlayerSanctions(UGameInstance &GameInstance, const FUCIK_PlayerHandle &Player)
{
auto *Service = GameInstance.GetSubsystem<UUCIKPlatformSubsystem>();
if (!Service)
return;
Service->QuerySanctions(
Player, FBetideCallback<TArray<FUCIK_Sanction>>::CreateWeakLambda(
&GameInstance, [](const TBetideResult<TArray<FUCIK_Sanction>> &Result) {
if (!Result.bOk)
{
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
return;
}
for (const FUCIK_Sanction &Sanction : Result.GetValue())
UE_LOG(LogUCIK, Log, TEXT("%s: %s"), *Sanction.Action,
*Sanction.ReferenceId);
}));
}Server kicks require the player’s handle to be reported through UUCIKPlayerLinkComponent on their PlayerController. Call the kick from trusted server logic; the host cannot kick itself.
Block, mute, or remove
Block a player
Loading the interactive viewer.
Unblock a player
Loading the interactive viewer.
List blocked players
Loading the interactive viewer.
Save a local mute
Loading the interactive viewer.
Remove a player from the server
Loading the interactive viewer.
Game module dependencies: UCIKCore, BetideCore.
Block a player
#include "Engine/GameInstance.h"
#include "Social/UCIKSocialSubsystem.h"
#include "UCIKCore.h"
void BlockPlayer(UGameInstance &GameInstance, const FUCIK_PlayerHandle &Player)
{
auto *Service = GameInstance.GetSubsystem<UUCIKSocialSubsystem>();
if (!Service)
return;
Service->BlockPlayer(
Player,
FBetideCallback<bool>::CreateWeakLambda(&GameInstance, [](const TBetideResult<bool> &Result) {
if (!Result.bOk)
{
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
return;
}
UE_LOG(LogUCIK, Log, TEXT("Block completed: %d"), Result.GetValue());
}));
}Unblock a player
#include "Engine/GameInstance.h"
#include "Social/UCIKSocialSubsystem.h"
#include "UCIKCore.h"
void UnblockPlayer(UGameInstance &GameInstance, const FUCIK_PlayerHandle &Player)
{
auto *Service = GameInstance.GetSubsystem<UUCIKSocialSubsystem>();
if (!Service)
return;
Service->UnblockPlayer(
Player,
FBetideCallback<bool>::CreateWeakLambda(&GameInstance, [](const TBetideResult<bool> &Result) {
if (!Result.bOk)
{
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
return;
}
UE_LOG(LogUCIK, Log, TEXT("Unblock completed: %d"), Result.GetValue());
}));
}List blocked players
#include "Engine/GameInstance.h"
#include "Social/UCIKSocialSubsystem.h"
#include "UCIKCore.h"
void ListBlockedPlayers(UGameInstance &GameInstance)
{
auto *Service = GameInstance.GetSubsystem<UUCIKSocialSubsystem>();
if (!Service)
return;
Service->GetBlockedPlayers(FBetideCallback<TArray<FUCIK_PlayerHandle>>::CreateWeakLambda(
&GameInstance, [](const TBetideResult<TArray<FUCIK_PlayerHandle>> &Result) {
if (!Result.bOk)
{
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Result.Error.GetLogString());
return;
}
for (const FUCIK_PlayerHandle &Player : Result.GetValue())
UE_LOG(LogUCIK, Log, TEXT("%s"), *Player.ToString());
}));
}Save a local mute
#include "Engine/GameInstance.h"
#include "Social/UCIKSocialSubsystem.h"
#include "UCIKCore.h"
void SetPlayerMute(UGameInstance &GameInstance, const FUCIK_PlayerHandle &Player, bool bMuted)
{
if (auto *Service = GameInstance.GetSubsystem<UUCIKSocialSubsystem>())
{
Service->SetPlayerMuted(Player, bMuted);
UE_LOG(LogUCIK, Log, TEXT("Muted: %d"), Service->IsPlayerMuted(Player));
}
}Remove a player from the server
#include "Engine/GameInstance.h"
#include "Platform/UCIKPlatformSubsystem.h"
#include "UCIKCore.h"
void RemovePlayerFromServer(UGameInstance &GameInstance, const FUCIK_PlayerHandle &Player,
const FText &Reason)
{
if (auto *Service = GameInstance.GetSubsystem<UUCIKPlatformSubsystem>())
{
const FBetideError Error = Service->KickPlayerFromServer(Player, Reason);
if (Error.IsError())
UE_LOG(LogUCIK, Warning, TEXT("%s"), *Error.GetLogString());
else
UE_LOG(LogUCIK, Log, TEXT("Player removed"));
}
}Blocking, local voice muting, lobby removal, and server kicks are separate actions. Persistent mutes are stored on this machine. A sanction with no expiry is permanent; a failed query must not be treated as a clean record.