Skip to content

Commit

Permalink
add client interface
Browse files Browse the repository at this point in the history
  • Loading branch information
gafferongames committed Dec 25, 2023
1 parent 2b13eb0 commit e272692
Show file tree
Hide file tree
Showing 3 changed files with 359 additions and 289 deletions.
291 changes: 2 additions & 289 deletions yojimbo.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
#include "yojimbo_network_info.h"
#include "yojimbo_server_interface.h"
#include "yojimbo_base_server.h"
#include "yojimbo_server.h"
#include "yojimbo_client_interface.h"

/** @file */

Expand Down Expand Up @@ -83,295 +85,6 @@ void ShutdownYojimbo();

namespace yojimbo
{
/**
Dedicated server implementation.
*/

class Server : public BaseServer
{
public:

Server( Allocator & allocator, const uint8_t privateKey[], const Address & address, const ClientServerConfig & config, Adapter & adapter, double time );

~Server();

void Start( int maxClients );

void Stop();

void DisconnectClient( int clientIndex );

void DisconnectAllClients();

void SendPackets();

void ReceivePackets();

void AdvanceTime( double time );

bool IsClientConnected( int clientIndex ) const;

uint64_t GetClientId( int clientIndex ) const;

netcode_address_t * GetClientAddress( int clientIndex ) const;

int GetNumConnectedClients() const;

void ConnectLoopbackClient( int clientIndex, uint64_t clientId, const uint8_t * userData );

void DisconnectLoopbackClient( int clientIndex );

bool IsLoopbackClient( int clientIndex ) const;

void ProcessLoopbackPacket( int clientIndex, const uint8_t * packetData, int packetBytes, uint64_t packetSequence );

const Address & GetAddress() const { return m_boundAddress; }

private:

void TransmitPacketFunction( int clientIndex, uint16_t packetSequence, uint8_t * packetData, int packetBytes );

int ProcessPacketFunction( int clientIndex, uint16_t packetSequence, uint8_t * packetData, int packetBytes );

void ConnectDisconnectCallbackFunction( int clientIndex, int connected );

void SendLoopbackPacketCallbackFunction( int clientIndex, const uint8_t * packetData, int packetBytes, uint64_t packetSequence );

static void StaticConnectDisconnectCallbackFunction( void * context, int clientIndex, int connected );

static void StaticSendLoopbackPacketCallbackFunction( void * context, int clientIndex, const uint8_t * packetData, int packetBytes, uint64_t packetSequence );

ClientServerConfig m_config;
netcode_server_t * m_server;
Address m_address; // original address passed to ctor
Address m_boundAddress; // address after socket bind, eg. valid port
uint8_t m_privateKey[KeyBytes];
};

/**
The set of client states.
*/

enum ClientState
{
CLIENT_STATE_ERROR = -1,
CLIENT_STATE_DISCONNECTED = 0,
CLIENT_STATE_CONNECTING,
CLIENT_STATE_CONNECTED,
};

/**
The common interface for all clients.
*/

class ClientInterface
{
public:

virtual ~ClientInterface() {}

/**
Set the context for reading and writing packets.
This is optional. It lets you pass in a pointer to some structure that you want to have available when reading and writing packets via Stream::GetContext.
Typical use case is to pass in an array of min/max ranges for values determined by some data that is loaded from a toolchain vs. being known at compile time.
If you do use a context, make sure the same context data is set on client and server, and include a checksum of the context data in the protocol id.
*/

virtual void SetContext( void * context ) = 0;

/**
Disconnect from the server.
*/

virtual void Disconnect() = 0;

/**
Send packets to server.
*/

virtual void SendPackets() = 0;

/**
Receive packets from the server.
*/

virtual void ReceivePackets() = 0;

/**
Advance client time.
Call this at the end of each frame to advance the client time forward.
IMPORTANT: Please use a double for your time value so it maintains sufficient accuracy as time increases.
*/

virtual void AdvanceTime( double time ) = 0;

/**
Is the client connecting to a server?
This is true while the client is negotiation connection with a server.
@returns true if the client is currently connecting to, but is not yet connected to a server.
*/

virtual bool IsConnecting() const = 0;

/**
Is the client connected to a server?
This is true once a client successfully finishes connection negotiatio, and connects to a server. It is false while connecting to a server.
@returns true if the client is connected to a server.
*/

virtual bool IsConnected() const = 0;

/**
Is the client in a disconnected state?
A disconnected state corresponds to the client being in the disconnected, or in an error state. Both are logically "disconnected".
@returns true if the client is disconnected.
*/

virtual bool IsDisconnected() const = 0;

/**
Is the client in an error state?
When the client disconnects because of an error, it enters into this error state.
@returns true if the client is in an error state.
*/

virtual bool ConnectionFailed() const = 0;

/**
Get the current client state.
*/

virtual ClientState GetClientState() const = 0;

/**
Get the client index.
The client index is the slot number that the client is occupying on the server.
@returns The client index in [0,maxClients-1], where maxClients is the number of client slots allocated on the server in Server::Start.
*/

virtual int GetClientIndex() const = 0;

/**
Get the client id.
The client id is a unique identifier of this client.
@returns The client id.
*/

virtual uint64_t GetClientId() const = 0;

/**
Get the current client time.
@see Client::AdvanceTime
*/

virtual double GetTime() const = 0;

/**
Create a message of the specified type.
@param type The type of the message to create. The message types corresponds to the message factory created by the adaptor set on this client.
*/

virtual Message * CreateMessage( int type ) = 0;

/**
Helper function to allocate a data block.
This is typically used to create blocks of data to attach to block messages. See BlockMessage for details.
@param bytes The number of bytes to allocate.
@returns The pointer to the data block. This must be attached to a message via Client::AttachBlockToMessage, or freed via Client::FreeBlock.
*/

virtual uint8_t * AllocateBlock( int bytes ) = 0;

/**
Attach data block to message.
@param message The message to attach the block to. This message must be derived from BlockMessage.
@param block Pointer to the block of data to attach. Must be created via Client::AllocateBlock.
@param bytes Length of the block of data in bytes.
*/

virtual void AttachBlockToMessage( Message * message, uint8_t * block, int bytes ) = 0;

/**
Free a block of memory.
@param block The block of memory created by Client::AllocateBlock.
*/

virtual void FreeBlock( uint8_t * block ) = 0;

/**
Can we send a message on a channel?
@param channelIndex The channel index in range [0,numChannels-1].
@returns True if a message can be sent over the channel, false otherwise.
*/

virtual bool CanSendMessage( int channelIndex ) const = 0;

/**
Send a message on a channel.
@param channelIndex The channel index in range [0,numChannels-1].
@param message The message to send.
*/

virtual void SendMessage( int channelIndex, Message * message ) = 0;

/**
Receive a message from a channel.
@param channelIndex The channel index in range [0,numChannels-1].
@returns The message received, or NULL if no message is available. Make sure to release this message by calling Client::ReleaseMessage.
*/

virtual Message * ReceiveMessage( int channelIndex ) = 0;

/**
Release a message.
Call this for messages received by Client::ReceiveMessage.
@param message The message to release.
*/

virtual void ReleaseMessage( Message * message ) = 0;

/**
Get client network info.
Call this to receive information about the client network connection to the server, eg. round trip time, packet loss %, # of packets sent and so on.
@param info The struct to be filled with network info [out].
*/

virtual void GetNetworkInfo( NetworkInfo & info ) const = 0;

/**
Connect to server over loopback.
This allows you to have local clients connected to a server, for example for integrated server or singleplayer.
@param clientIndex The index of the client.
@param clientId The unique client id.
@param maxClients The maximum number of clients supported by the server.
*/

virtual void ConnectLoopback( int clientIndex, uint64_t clientId, int maxClients ) = 0;

/**
Disconnect from server over loopback.
*/

virtual void DisconnectLoopback() = 0;

/**
Is this a loopback client?
@returns true if the client is a loopback client, false otherwise.
*/

virtual bool IsLoopback() const = 0;

/**
Process loopback packet.
Use this to pass packets from a server directly to the loopback client.
@param packetData The packet data to process.
@param packetBytes The number of bytes of packet data.
@param packetSequence The packet sequence number.
*/

virtual void ProcessLoopbackPacket( const uint8_t * packetData, int packetBytes, uint64_t packetSequence ) = 0;
};

/**
Functionality that is common across all client implementations.
*/
Expand Down
Loading

0 comments on commit e272692

Please sign in to comment.