Skip to main content

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.

#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);
}

Beginning an Anti-Cheat session is an asynchronous process. Once the process completes, the beginSessionCallback is called.

#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());
}
}

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.

FGCSDK_AC_ResultCode endSessionResult = FGCSDK_AC_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.

#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);
}

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.

FGSSDK_AC_ResultCode endResult = FGSSDK_AC_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.

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);
}

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.

// 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
);
}

When the message is received on the game server, it should be provided to the server's Anti-Cheat interface by calling ReceiveMessageFromClient().

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);
}

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.

// 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
);
}

When the message is received on the game client, it should be provided to the client's Anti-Cheat interface by calling ReceiveMessageFromServer().

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);
}

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.

// 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);
}