SDK Integration
Both the client and server SDK libraries contain an Anti-Cheat interface. These interfaces work together between your game client and server, and utilise the protection provided by the FACEIT Anti-Cheat client application running on players' machines.
Starting an Anti-Cheat Session
Client
See the page on Authentication for information on how to authenticate the player with the FACEIT Client SDK. This authentication must be performed successfully before any Anti-Cheat interface functions will work.
Once authenticated, an Anti-Cheat session can be created by calling the BeginSession()
function, as demonstrated in the example below. If the game is not started with the AC launcher, BeginSession()
will return an error. To check if the AC is available, the IsAvailable()
function can be used.
- C++
- UE4
- C#
#include "FACEITGameClientSDK/Anticheat/Anticheat.h"
void MyGameClientInstance::ActivateAntiCheat()
{
if ( !FGCSDK_AC_IsAvailable() )
{
// If the AC is not available, the user probably hasn't started
// the game using the AC launcher. The game could run custom
// logic here, eg. disabling access to menus for matches where
// AC is needed, or showing the user a popup to inform them
// that AC protection is required.
return;
}
FGCSDK_AC_BeginSessionSettingsData settings {};
// The session's user data can be whatever is convenient for the use case.
// User data is passed into any callbacks that are called by the
// Anti-Cheat implementation. For a persistent game instance class,
// passing "this" allows you to easily call functions on the instance
// when responding to a callback.
settings.userData = this;
// This callback is called once the FGCSDK_AC_BeginSession() request completes.
settings.beginSessionCallback = &Callback_AC_OnBeginSession;
// This callback is called when an Anti-Cheat message is ready
// to be sent to the game server.
settings.messageToServerCallback = &Callback_AC_OnMessageToServer;
// A call to FGCSDK_AC_BeginSession() activates Anti-Cheat protection for the game
// client. This should be used whenever it is important that the player's in-game
// actions are legal. This function could be called when the game client starts,
// or when a player is about to connect to an Anti-Cheat protected server,
// depending on the developer's preference.
FGCSDK_AC_ResultCode beginSessionResult = FGCSDK_AC_BeginSession(&settings);
}
#include "FACEITUnrealClientPlugin/Anticheat/UFUCP_Anticheat.h"
void UMyGameClientInstance::ActivateAntiCheat()
{
if ( !UFUCP_Anticheat::IsAvailable() )
{
// If the AC is not available, the user probably hasn't started
// the game using the AC launcher. The game could run custom
// logic here, eg. disabling access to menus for matches where
// AC is needed, or showing the user a popup to inform them
// that AC protection is required.
return;
}
UFUCP_Anticheat_BeginSessionSettings* Settings =
NewObject<UFUCP_Anticheat_BeginSessionSettings>(this);
// This callback is called once the UFUCP_Anticheat::BeginSession() request completes.
Settings.BeginSessionCallback.AddDynamic(this, &UMyGameClientInstance::AC_OnBeginSession)
// This callback is called when an Anti-Cheat message is ready
// to be sent to the game server.
Settings.MessageToServerCallback.AddDynamic(this, &UMyGameClientInstance::AC_OnMessageToServer);
// A call to UFUCP_Anticheat::BeginSession() activates Anti-Cheat protection for the game
// client. This should be used whenever it is important that the player's in-game
// actions are legal. This function could be called when the game client starts,
// or when a player is about to connect to an Anti-Cheat protected server,
// depending on the developer's preference.
EFUCP_Anticheat_ResultCode BeginSessionResult = UFUCP_Anticheat::BeginSession(Settings);
}
using System;
using FACEITGameClientSDK;
public partial class MyGameClientInstance
{
public void ActivateAntiCheat()
{
if ( !Anticheat.IsAvailable() )
{
// If the AC is not available, the user probably hasn't started
// the game using the AC launcher. The game could run custom
// logic here, eg. disabling access to menus for matches where
// AC is needed, or showing the user a popup to inform them
// that AC protection is required.
return;
}
// A call to BeginSession() activates Anti-Cheat protection for the game
// client. This should be used whenever it is important that the player's in-game
// actions are legal. This function could be called when the game client starts,
// or when a player is about to connect to an Anti-Cheat protected server,
// depending on the developer's preference.
Anticheat.ResultCode beginSessionResult = Anticheat.BeginSession(
// C# automatically infers the current MyGameClientInstance object
// when mapping these callbacks to member functions. The functions
// used here are explained in detail in later sections.
new Anticheat.BeginSessionSettingsData
{
// This callback is called once the BeginSession() request completes.
BeginSessionCallback = AC_OnBeginSession,
// This callback is called when an Anti-Cheat message is ready
// to be sent to the game server.
MessageToServerCallback = AC_OnMessageToServer
});
}
}
Beginning an Anti-Cheat session is an asynchronous process. Once the process completes, the beginSessionCallback
is called.
- C++
- UE4
- C#
#include "FACEITGameServerSDK/Utility/StringHelpers.h"
// Static callback function:
void Callback_AC_OnBeginSession(const FGCSDK_AC_BeginSessionCallbackInfo* info)
{
// Call into game instance - see below.
static_cast<MyGameServerInstance*>(info->userData)->AC_OnBeginSession(info);
}
void MyGameServerInstance::AC_OnBeginSession(const FGCSDK_AC_BeginSessionCallbackInfo* info)
{
// info->resultCode holds the result of the request.
// A client may only connect to an Anti-Cheat protected
// game server if the FGCSDK_AC_BeginSession() request was successful.
if ( info->resultCode == FGSSDK_MLC_OK )
{
// The session started correctly.
// Perform any post-init tasks here.
}
else
{
// The session failed to start.
Log("Anti-Cheat session failed to start: %s",
FGCSDK_ToString(&FGCSDK_AC_ResultCode_GetDescription, info->resultCode).c_str());
}
}
void UMyGameClientInstance::AC_OnBeginSession(const FFUCP_Anticheat_BeginSessionCallbackInfo& Info)
{
// Info.ResultCode holds the result of the request.
// A client may only connect to an Anti-Cheat protected
// game server if the UFUCP_Anticheat::BeginSession() request
// was successful.
if ( Info.ResultCode == FGSSDK_MLC_OK )
{
// The session started correctly.
// Perform any post-init tasks here.
}
else
{
// The session failed to start.
UE_LOG(LogMyGame, Error, TEXT("Anti-Cheat session failed to start: %s"),
*UFUCP_Anticheat::GetResultCodeDescription(Info.ResultCode));
}
}
public partial class MyGameClientInstance
{
private void AC_OnBeginSession(Anticheat.BeginSessionCallbackInfo data)
{
// info->resultCode holds the result of the request.
// A client may only connect to an Anti-Cheat protected
// game server if the Anticheat.BeginSession() request was successful.
if (data.ResultCode == Anticheat.ResultCode.OK)
{
// The session started correctly.
// Perform any post-init tasks here.
}
else
{
// The session failed to start.
Console.WriteLine("Anti-Cheat session failed to start: " +
Anticheat.GetResultCodeDescription(data.ResultCode));
}
}
}
Later, when Anti-Cheat protection is no longer required, the session should be ended. This should happen once the player has disconnected from any Anti-Cheat protected server.
Although ending a session returns a result code, receiving any code other than OK
may be treated as an exceptional condition, and may indicate an issue with the user's underlying Anti-Cheat service.
- C++
- UE4
- C#
FGCSDK_AC_ResultCode endSessionResult = FGCSDK_AC_EndSession();
EFUCP_Anticheat_ResultCode EndSessionResult = UFUCP_Anticheat::EndSession();
Anticheat.ResultCode endSessionResult = Anticheat.EndSession();
Server
See the page on Authentication for information on how to provide an authentication token to the server SDK. This authentication must be performed successfully before any Anti-Cheat interface functions will work.
Once authenticated, an Anti-Cheat session can be created by calling the BeginSession()
function, as demonstrated in the example below.
- C++
- UE4
- C#
#include "FACEITGameServerSDK/Anticheat/Anticheat.h"
void MyGameServerInstance::ActivateAntiCheat()
{
FGSSDK_AC_BeginSessionSettingsData settings {};
// The session's user data can be whatever is convenient for the use case.
// User data is passed into any callbacks that are called by the
// Anti-Cheat implementation. For a persistent game instance class,
// passing "this" allows you to easily call functions on the instance
// when responding to a callback.
settings.userData = this;
// Number of seconds to allow clients to authenticate after calling FGSSDK_AC_RegisterClient().
// A reasonable value for this timeout is 30 seconds.
settings.clientAuthenticationTimeoutSecs = 30;
// This callback is called when a player should be kicked from the server.
settings.kickCallback = &Callback_AC_OnKick;
// This callback is called when an Anti-Cheat message is ready
// to be sent to a specific client.
settings.messageToClientCallback = &Callback_AC_OnMessageToClient;
// A call to FGSSDK_AC_BeginSession() activates anti-cheat protection for the game server.
// This should be used whenever it is important that connected players' actions
// within the game are legal. The connected players should already have activated
// their own client Anti-Cheat sessions before this is called.
FGSSDK_AC_ResultCode beginResult = FGSSDK_AC_BeginSession(&settings);
}
#include "FACEITUnrealServerPlugin/Anticheat/UFUSP_Anticheat.h"
void UMyGameServerInstance::ActivateAntiCheat()
{
UFUSP_Anticheat_BeginSessionSettings* Settings =
NewObject<UFUSP_Anticheat_BeginSessionSettings>(this);
// Number of seconds to allow clients to authenticate after calling
// UFUSP_Anticheat::RegisterClient(). A reasonable value for this timeout
// is 30 seconds.
Settings.ClientAuthenticationTimeoutSecs = 30;
// This callback is called when a player should be kicked from the server.
Settings.KickCallback.AddDynamic(this, UMyGameServerInstance::AC_OnKick);
// This callback is called when an Anti-Cheat message is ready
// to be sent to a specific client.
Settings.MessageToClientCallback.AddDynamic(this, UMyGameServerInstance::AC_OnMessageToClient);
// A call to UFUSP_Anticheat::BeginSession() activates anti-cheat protection for the game server.
// This should be used whenever it is important that connected players' actions
// within the game are legal. The connected players should already have activated
// their own client Anti-Cheat sessions before this is called.
EFUSP_Anticheat_ResultCode BeginResult = UFUSP_Anticheat::BeginSession(Settings);
}
public partial class MyGameServerInstance
{
public void ActivateAntiCheat()
{
// A call to BeginSession() activates anti-cheat protection for the game server.
// This should be used whenever it is important that connected players' actions
// within the game are legal. The connected players should already have activated
// their own client Anti-Cheat sessions before this is called.
Anticheat.ResultCode beginSessionResult = Anticheat.BeginSession(
// C# automatically infers the current MyGameClientInstance object
// when mapping these callbacks to member functions. The functions
// used here are explained in detail in later sections.
new Anticheat.BeginSessionSettingsData
{
// Number of seconds to allow clients to authenticate after calling RegisterClient().
// A reasonable value for this timeout is 30 seconds.
ClientAuthenticationTimeoutSecs = 30,
// This callback is called when a player should be kicked from the server.
OnKickRequestCallback = AC_OnKick,
// This callback is called when an Anti-Cheat message is ready
// to be sent to a specific client.
OnMessageToClientCallback = AC_OnMessageToClient,
});
}
}
Later, when Anti-Cheat protection is no longer required, the session should be ended. Although ending a session returns a result code, receiving any code other than OK
may be treated as an exceptional condition.
- C++
- UE4
- C#
FGSSDK_AC_ResultCode endResult = FGSSDK_AC_EndSession();
EFUSP_Anticheat_ResultCode EndSessionResult = UFUSP_Anticheat::EndSession();
Anticheat.ResultCode endSessionResult = Anticheat.EndSession();
Registering Connected Players
Any player who connects to the game server must be registered with the FACEIT Anti-Cheat by calling RegisterClient()
on the server, and un-registered when they leave by calling UnregisterClient()
. A server Anti-Cheat session must be active when these functions are called.
- C++
- UE4
- C#
void MyGameServerInstance::ClientConnected(ConnectedClient* clientWhoJoined)
{
FGSSDK_AC_RegisterClientInfo info {};
// This is a string that uniquely identifies the client
// within the game, for the purposes of FACEIT account
// linking. For example, if the client has authenticated
// with the FACEIT SDK using Steam, this string would
// be their Steam ID.
std::string gameID = clientWhoJoined->GetGameID();
info.gameID = gameID.c_str();
// Arbitrary user data may be set for this client. When
// callbacks are called later, eg. to send a message to
// this client, the user data will also be passed.
info.clientUserData = clientWhoJoined;
// Register the client with the Anti-Cheat implementation.
FGSSDK_AC_ResultCode result = FGSSDK_AC_RegisterClient(&info);
}
void MyGameServerInstance::ClientDisconnected(ConnectedClient* clientWhoLeft)
{
FGSSDK_AC_UnregisterClientInfo info {};
// This should be the same game ID that was provided when
// this client was registered.
std::string gameID = clientWhoLeft->GetGameID();
info.gameID = gameID.c_str();
// Unregister the client from the Anti-Cheat implementation.
FGSSDK_AC_ResultCode result = FGSSDK_AC_UnregisterClient(&info);
}
void UMyGameServerInstance::ClientConnected(UPlayer* ClientWhoJoined)
{
UFUSP_Anticheat_RegisterClientInfo Info =
NewObject<UFUSP_Anticheat_RegisterClientInfo>(this);
// This is a string that uniquely identifies the client
// within the game, for the purposes of FACEIT account
// linking. For example, if the client has authenticated
// with the FACEIT SDK using Steam, this string would
// be their Steam ID. The game is expected to compute
// and return the relevant string here.
Info.GameID = GetClientGameID(ClientWhoJoined);
// Arbitrary user data may be set for this client. When
// callbacks are called later, eg. to send a message to
// this client, the user data will also be passed.
Info.ClientUserData = ClientWhoJoined;
// Register the client with the Anti-Cheat implementation.
EFUSP_Anticheat_ResultCode Result = UFUSP_Anticheat::RegisterClient(Info);
}
void UMyGameServerInstance::ClientDisconnected(UPlayer* ClientWhoLeft)
{
FFUSP_Anticheat_UnregisterClientInfo Info {};
// This should be the same game ID that was provided when
// this client was registered.
Info.GameID = GetClientGameID(ClientWhoLeft);
// Unregister the client from the Anti-Cheat implementation.
EFUSP_Anticheat_ResultCode Result = UFUSP_Anticheat::UnregisterClient(Info);
}
public partial class MyGameServerInstance
{
void ClientConnected(ConnectedClient clientWhoJoined)
{
// Register the client with the Anti-Cheat implementation.
Anticheat.ResultCode result = Anticheat.RegisterClient(
new Anticheat.RegisterClientInfo
{
// This is a string that uniquely identifies the client
// within the game, for the purposes of FACEIT account
// linking. For example, if the client has authenticated
// with the FACEIT SDK using Steam, this string would
// be their Steam ID.
GameID = clientWhoJoined.GetGameID(),
// Arbitrary user data may be set for this client. When
// callbacks are called later, eg. to send a message to
// this client, the user data will also be passed.
ClientUserData = clientWhoJoined
});
}
void ClientDisconnected(ConnectedClient clientWhoLeft)
{
// Unregister the client from the Anti-Cheat implementation.
Anticheat.ResultCode result = Anticheat.UnregisterClient(
new Anticheat.UnregisterClientInfo
{
// This should be the same game ID that was provided when
// this client was registered.
GameID = clientWhoLeft.GetGameID(),
});
}
}
Message Callbacks
The FACEIT Anti-Cheat client and server implementations communicate with one another in order to function. When beginning a session for either the Anti-Cheat client or server, a messageToServerCallback
or messageToClientCallback
is specified in the session settings. This is a callback which is called whenever one Anti-Cheat implementation emits a message that must be sent over the network to its counterpart.
Since the FACEIT Anti-Cheat is game engine agnostic, it is up to the game developer to take any emitted message and transmit it securely over the network.
Client to Server
When the FACEIT Anti-Cheat client emits a message, this message will be provided on the messageToServerCallback
that was specified when calling BeginSession()
on the client. This message should be transmitted securely to the game server that the client is connected to.
- C++
- UE4
- C#
// Static callback function:
void Callback_AC_OnMessageToServer(const FGCSDK_AC_MessageToServerCallbackData* data)
{
// Call into game instance - see below.
static_cast<MyGameClientInstance*>(info->userData)->AC_OnMessageToServer(data);
}
void MyGameClientInstance::AC_OnMessageToServer(const FGCSDK_AC_MessageToServerCallbackData* data)
{
// Secure transmission of data between the game client and server
// must be implemented by the game developer.
TransmitSecureAnticheatMessageToServer(
data->messageBuffer,
data->messageBufferSize
);
}
void UMyGameClientInstance::AC_OnMessageToServer(const FFUCP_Anticheat_MessageToServerCallbackInfo& Info)
{
// Secure transmission of data between the game client and server
// must be implemented by the game developer.
TransmitSecureAnticheatMessageToServer(Info.Message);
}
public partial class MyGameClientInstance
{
private void AC_OnMessageToServer(Anticheat.MessageToServerCallbackData data)
{
// Secure transmission of data between the game client and server
// must be implemented by the game developer.
TransmitSecureAnticheatMessageToServer(data.Message);
}
}
When the message is received on the game server, it should be provided to the server's Anti-Cheat interface by calling ReceiveMessageFromClient()
.
- C++
- UE4
- C#
void MyGameServerInst::ReceiveSecureAnticheatMessageFromClient(
ConnectedClient* clientWhoSentMessage,
FGSSDK_ConstOpaquePtr messageBuffer,
FGSSDK_Size messageBufferSize
)
{
FGSSDK_AC_MessageFromClientData message {};
// The Anti-Cheat implementation must know which client this
// message came from. The game ID here should be the same as
// was passed when this client was registered.
std::string gameID = clientWhoSentMessage.GetGameID();
message.gameID = gameID.c_str();
// Pass in the message data that was received.
message.messageBuffer = messageBuffer;
message.messageBufferSize = messageBufferSize;
// Pass the message to the Anti-Cheat implementation.
FGSSDK_AC_ReceiveMessageFromClient(&message);
}
void UMyGameServerInstance::ReceiveSecureAnticheatMessageFromClient(
UPlayer* ClientWhoSentMessage,
const TArray<uint8>& Message
)
{
FFUSP_Anticheat_MessageFromClientData Data {};
// The Anti-Cheat implementation must know which client this
// message came from. The game ID here should be the same as
// was passed when this client was registered.
Data.GameID = GetClientGameID(ClientWhoSentMessage);
// Pass in the message data that was received.
Data.Message = Message;
// Pass the message to the Anti-Cheat implementation.
UFUSP_Anticheat::ReceiveMessageFromClient(Data);
}
public partial class MyGameServerInstance
{
private void ReceiveSecureAnticheatMessageFromClient(
ConnectedClient clientWhoSentMessage,
string message
)
{
// Call ReceiveMessageFromClient() to pass the message to the
// Anti-Cheat implementation.
Anticheat.ResultCode result = Anticheat.ReceiveMessageFromClient(
new Anticheat.MessageFromClientData
{
// The Anti-Cheat implementation must know which client this
// message came from. The game ID here should be the same as
// was passed when this client was registered.
Client = clientWhoSentMessage.GetGameID(),
// Pass in the message data that was received.
Message = message
});
}
}
Server to Client
Conversely, when the FACEIT Anti-Cheat server emits a message, this message will be provided on the messageToClientCallback
that was provided when calling BeginSession()
. The intended recipient is indicated by the gameID
contained within the callback data. The user data provided when the client was registered is also passed to the callback.
The game should transmit the message securely to the target client.
- C++
- UE4
- C#
// Static callback function:
void Callback_AC_OnMessageToClient(const FGSSDK_AC_MessageToClientCallbackInfo* data)
{
// Call into game instance - see below.
static_cast<MyGameServerInstance*>(info->userData)->AC_OnMessageToClient(data);
}
void MyGameServerInstance::AC_OnMessageToClient(const FGSSDK_AC_MessageToClientCallbackInfo* data)
{
// Secure transmission of data between the game server and client
// must be implemented by the game developer.
TransmitSecureAnticheatMessageToClient(
static_cast<ConnectedClient*>(data->clientUserData)
data->messageBuffer,
data->messageBufferSize
);
}
void UMyGameServerInstance::AC_OnMessageToClient(const FFUSP_Anticheat_MessageToClientCallbackData& Data)
{
// Secure transmission of data between the game server and client
// must be implemented by the game developer.
TransmitSecureAnticheatMessageToClient(
CastChecked<UPlayer>(Data.ClientUserData),
Data.Message
);
}
public partial class MyGameServerInstance
{
private void AC_OnMessageToClient(Anticheat.MessageToClientCallbackInfo data)
{
// Secure transmission of data between the game server and client
// must be implemented by the game developer.
TransmitSecureAnticheatMessageToClient(
(ConnectedClient)data.ClientUserData,
data.Message
);
}
}
When the message is received on the game client, it should be provided to the client's Anti-Cheat interface by calling ReceiveMessageFromServer()
.
- C++
- UE4
- C#
void MyGameClientInst::ReceiveSecureAnticheatMessageFromServer(
FGCSDK_ConstOpaquePtr messageBuffer,
FGCSDK_Size messageBufferSize
)
{
FGCSDK_AC_MessageFromServerData message {};
// Pass in the message data that was received.
message.messageBuffer = messageBuffer;
message.messageBufferSize = messageBufferSize;
// Pass the message to the Anti-Cheat implementation.
FGCSDK_AC_ReceiveMessageFromServer(&message);
}
void UMyGameClientInstance::ReceiveSecureAnticheatMessageFromServer(const TArray<uint8> Message)
{
FFUCP_Anticheat_MessageFromServerData Data {};
// Pass in the message data that was received.
Data.Message = Message;
// Pass the message to the Anti-Cheat implementation.
UFUCP_Anticheat::ReceiveMessageFromServer(Message);
}
class MyGameClientInstance
{
private void ReceiveSecureAnticheatMessageFromServer(string message)
{
// Call ReceiveMessageFromServer() to pass the message to the
// Anti-Cheat implementation.
Anticheat.ResultCode result = Anticheat.ReceiveMessageFromServer(
new Anticheat.MessageFromServerData
{
// Pass in the message data that was received.
Message = message,
});
}
}
Kick Callback
Sometimes a player may need to be kicked from the server, because their FACEIT Anti-Cheat authentication failed, or because they have been banned.
A kickCallback
is provided to the FACEIT Anti-Cheat BeginSession()
call. The Anti-Cheat will call this callback if a player should be kicked from the server.
- C++
- UE4
- C#
// Static callback function:
void Callback_AC_OnKick(const FGSSDK_AC_KickCallbackInfo* data)
{
// Call into game instance - see below.
static_cast<MyGameServerInstance*>(info->userData)->AC_OnKick(data);
}
void MyGameServerInstance::AC_OnKick(const FGSSDK_AC_KickCallbackInfo* info)
{
// This is the client who needs to be kicked.
ConnectedClient* client = static_cast<ConnectedClient*>(info->clientUserData);
// It is up to the game developer to convert the FACEIT Anti-Cheat kick
// reason code into an appropriate string to display to the player.
std::string kickReason = GetLocalisedKickReason(info->kickReason);
// Kick this player from the server.
KickPlayer(client, kickReason);
}
void UMyGameServerInstance::AC_OnKick(const FFUSP_Anticheat_KickCallbackInfo& Info)
{
// This is the client who needs to be kicked.
UPlayer* Client = CastChecked<UPlayer>(Info.ClientUserData);
// It is up to the game developer to convert the FACEIT Anti-Cheat kick
// reason code into an appropriate string to display to the player.
FString KickReason = GetLocalisedKickReason(Info.KickReason);
// Kick this player from the server.
KickPlayer(Client, KickReason);
}
public partial class MyGameServerInstance
{
private void AC_OnKick(Anticheat.KickCallbackInfo info)
{
// This is the client who needs to be kicked.
ConnectedClient client = (ConnectedClient)info.Client;
// It is up to the game developer to convert the FACEIT Anti-Cheat kick
// reason code into an appropriate string to display to the player.
string kickReason = GetLocalisedKickReason(info.kickReason);
// Kick this player from the server.
KickPlayer(client, kickReason);
}
}