### Run Yojimbo Client Source: https://github.com/mas-bandwidth/yojimbo/blob/main/BUILDING.md Start a Yojimbo client that connects to the local server. ```bash ./bin/client ``` -------------------------------- ### Install libsodium on Linux Source: https://github.com/mas-bandwidth/yojimbo/blob/main/BUILDING.md Install the libsodium development library on Debian-based Linux systems using apt. ```bash sudo apt install libsodium-dev ``` -------------------------------- ### Run Yojimbo Server Source: https://github.com/mas-bandwidth/yojimbo/blob/main/BUILDING.md Start a Yojimbo server on localhost, listening on UDP port 40000. ```bash ./bin/server ``` -------------------------------- ### Install libsodium on MacOS Source: https://github.com/mas-bandwidth/yojimbo/blob/main/BUILDING.md Install the libsodium development library on MacOS using Homebrew. ```bash brew install libsodium ``` -------------------------------- ### Yojimbo GameServer Initialization and Event Handling Source: https://github.com/mas-bandwidth/yojimbo/blob/main/USAGE.md Initializes the Yojimbo server with a connection configuration and adapter, then starts the server and handles client connection/disconnection events. It prints the server's address upon successful startup. ```cpp static const uint8_t DEFAULT_PRIVATE_KEY[yojimbo::KeyBytes] = { 0 }; static const int MAX_PLAYERS = 64; GameServer::GameServer(const yojimbo::Address& address) : m_adapter(this), m_server(yojimbo::GetDefaultAllocator(), DEFAULT_PRIVATE_KEY, address, m_connectionConfig, m_adapter, 0.0) { // start the server m_server.Start(MAX_PLAYERS); if (!m_server.IsRunning()) { throw std::runtime_error("Could not start server at port " + std::to_string(address.GetPort())); } // print the port we got in case we used port 0 char buffer[256]; m_server.GetAddress().ToString(buffer, sizeof(buffer)); std::cout << "Server address is " << buffer << std::endl; // ... load game ... } void GameServer::ClientConnected(int clientIndex) { std::cout << "client " << clientIndex << " connected" << std::endl; } void GameServer::ClientDisconnected(int clientIndex) { std::cout << "client " << clientIndex << " disconnected" << std::endl; } ``` -------------------------------- ### Yojimbo Server Setup with Message Types and Configuration Source: https://github.com/mas-bandwidth/yojimbo/blob/main/USAGE.md Defines message types, channels, connection configuration, adapter, and message factory for a Yojimbo game server. The adapter provides callbacks for client connections and disconnections. ```cpp // a simple test message enum class GameMessageType { TEST, COUNT }; // two channels, one for each type that Yojimbo supports enum class GameChannel { RELIABLE, UNRELIABLE, COUNT }; // the client and server config struct GameConnectionConfig : yojimbo::ClientServerConfig { GameConnectionConfig() { numChannels = 2; channel[(int)GameChannel::RELIABLE].type = yojimbo::CHANNEL_TYPE_RELIABLE_ORDERED; channel[(int)GameChannel::UNRELIABLE].type = yojimbo::CHANNEL_TYPE_UNRELIABLE_UNORDERED; } }; // the adapter class GameAdapter : public yojimbo::Adapter { public: explicit GameAdapter(GameServer* server = NULL) : m_server(server) {} yojimbo::MessageFactory* CreateMessageFactory(yojimbo::Allocator& allocator) override { return YOJIMBO_NEW(allocator, GameMessageFactory, allocator); } void OnServerClientConnected(int clientIndex) override { if (m_server != NULL) { m_server->ClientConnected(clientIndex); } } void OnServerClientDisconnected(int clientIndex) override { if (m_server != NULL) { m_server->ClientDisconnected(clientIndex); } } private: GameServer* m_server; }; // the message factory YOJIMBO_MESSAGE_FACTORY_START(GameMessageFactory, (int)GameMessageType::COUNT); YOJIMBO_DECLARE_MESSAGE_TYPE((int)GameMessageType::TEST, TestMessage); YOJIMBO_MESSAGE_FACTORY_FINISH(); ``` -------------------------------- ### Get Match Token Source: https://github.com/mas-bandwidth/yojimbo/blob/main/matcher/README.md Retrieves a connection token based on the provided protocol ID and client ID. ```APIDOC ## GET /match/{protocolID}/{clientID} ### Description Retrieves a connection token using the specified protocol ID and client ID. ### Method GET ### Endpoint /match/{protocolID}/{clientID} ### Parameters #### Path Parameters - **protocolID** (string) - Required - The ID of the protocol. - **clientID** (string) - Required - The ID of the client. ### Request Example ```sh curl http://localhost:8081/match/123/42 ``` ### Response #### Success Response (200) - **token** (string) - The connection token. #### Response Example ```json { "token": "your_connection_token" } ``` ``` -------------------------------- ### Game Server Message Type Dispatch Source: https://github.com/mas-bandwidth/yojimbo/blob/main/USAGE.md A switch statement to dispatch received messages to specific handler functions based on their type. This example shows handling for a 'TEST' message type. ```cpp void GameServer::ProcessMessage(int clientIndex, yojimbo::Message* message) { switch (message->GetType()) { case (int)GameMessageType::TEST: ProcessTestMessage(clientIndex, (TestMessage*)message); break; default: break; } } ``` -------------------------------- ### Build Docker Image for Matcher Source: https://github.com/mas-bandwidth/yojimbo/blob/main/matcher/README.md Builds the Docker image for the matcher server. Ensure you are in the 'matcher' directory. ```sh docker build --tag=matcher . ``` -------------------------------- ### Client Initialization and Connection Source: https://github.com/mas-bandwidth/yojimbo/blob/main/USAGE.md Initializes the Yojimbo client with a unique client ID and attempts to establish an insecure connection to the game server. A random client ID is generated for development purposes. ```cpp OnlineGameScreen::OnlineGameScreen(const yojimbo::Address& serverAddress) : m_client(yojimbo::GetDefaultAllocator(), yojimbo::Address("0.0.0.0"), m_connectionConfig, m_adapter, 0.0) { uint64_t clientId; yojimbo_random_bytes((uint8_t*)&clientId, 8); m_client.InsecureConnect(DEFAULT_PRIVATE_KEY, clientId, m_serverAddress); } ``` -------------------------------- ### Build Yojimbo using Make Source: https://github.com/mas-bandwidth/yojimbo/blob/main/BUILDING.md Compile the Yojimbo library using make after generating the makefiles. The -j flag enables parallel compilation. ```bash make -j ``` -------------------------------- ### Run Yojimbo Unit Tests Source: https://github.com/mas-bandwidth/yojimbo/blob/main/BUILDING.md Execute the built unit tests for the Yojimbo library. ```bash ./bin/test ``` -------------------------------- ### Generate Visual Studio Project Files Source: https://github.com/mas-bandwidth/yojimbo/blob/main/BUILDING.md Use this command to generate Visual Studio 2019 project files from the command line within the yojimbo directory. ```bash premake5 vs2019 ``` -------------------------------- ### Run Docker Container for Matcher Source: https://github.com/mas-bandwidth/yojimbo/blob/main/matcher/README.md Runs the matcher Docker container, mapping port 8081. This makes the matcher accessible on your host machine. ```sh docker run -d -p 8081:8081 --name matcher matcher ``` -------------------------------- ### Client Sending and Receiving Test Messages Source: https://github.com/mas-bandwidth/yojimbo/blob/main/USAGE.md This C++ code shows how a Yojimbo client creates, sends, and processes a custom TestMessage. It includes logic for sending packets and receiving messages across different channels. ```cpp void OnlineGameScreen::SendMessageToTestServer() { TestMessage* message = (TestMessage*)m_client.CreateMessage((int)GameMessageType::TEST); message->m_data = 42; m_client.SendMessage((int)GameChannel::RELIABLE, message); } } m_client.SendPackets(); } void OnlineGameScreen::ProcessMessages() { for (int i = 0; i < m_connectionConfig.numChannels; i++) { yojimbo::Message* message = m_client.ReceiveMessage(i); while (message != NULL) { ProcessMessage(message); m_client.ReleaseMessage(message); message = m_client.ReceiveMessage(i); } } } void OnlineGameScreen::ProcessMessage(yojimbo::Message* message) { switch (message->GetType()) { case (int)GameMessageType::TEST: ProcessTestMessage((TestMessage*)message); break; default: break; } } void OnlineGameScreen::ProcessTestMessage(TestMessage* message) { std::cout << "Test message received from server with data " << message->m_data << std::endl; } ``` -------------------------------- ### Generate Makefiles on MacOS and Linux Source: https://github.com/mas-bandwidth/yojimbo/blob/main/BUILDING.md Generate makefiles for building the Yojimbo library on MacOS and Linux systems from the command line within the yojimbo directory. ```bash premake5 gmake ``` -------------------------------- ### Server Processing and Responding to Test Messages Source: https://github.com/mas-bandwidth/yojimbo/blob/main/USAGE.md This C++ code illustrates how a Yojimbo server processes an incoming TestMessage from a client and sends a response back. It logs the received data and forwards the message on the reliable channel. ```cpp void GameServer::ProcessTestMessage(int clientIndex, TestMessage* message) { std::cout << "Test message received from client " << clientIndex << " with data " << message->m_data << std::endl; TestMessage* testMessage = (TestMessage*)m_server.CreateMessage(clientIndex, (int)GameMessageType::TEST); testMessage->m_data = message->m_data; m_server.SendMessage(clientIndex, (int)GameChannel::RELIABLE, testMessage); } ``` -------------------------------- ### Game Server Update Loop Logic Source: https://github.com/mas-bandwidth/yojimbo/blob/main/USAGE.md The server's update method orchestrates critical network operations in a specific order: advancing time, receiving packets, processing messages, and finally sending packets. This order is crucial for minimizing latency. ```cpp void GameServer::Update(float dt) { // stop if server is not running if (!m_server.IsRunning()) { m_running = false; return; } // update server and process messages m_server.AdvanceTime(m_time); m_server.ReceivePackets(); ProcessMessages(); // ... process client inputs ... // ... update game ... // ... send game state to clients ... m_server.SendPackets(); } ``` -------------------------------- ### Yojimbo TestMessage Serialization Source: https://github.com/mas-bandwidth/yojimbo/blob/main/USAGE.md Defines a simple `TestMessage` class with an integer data member and implements basic serialization using Yojimbo's helper functions. This message can be serialized and deserialized by the Yojimbo stream. ```cpp class TestMessage : public yojimbo::Message { public: int m_data; TestMessage() : m_data(0) {} template bool Serialize(Stream& stream) { serialize_int(stream, m_data, 0, 512); return true; } YOJIMBO_VIRTUAL_SERIALIZE_FUNCTIONS(); }; ``` -------------------------------- ### Client Update Loop and Packet Sending Source: https://github.com/mas-bandwidth/yojimbo/blob/main/USAGE.md The client's update loop advances its internal time, receives network packets, and processes messages. It also includes logic to send a 'TestMessage' when the space key is pressed, provided the client is connected. ```cpp void OnlineGameScreen::Update(float dt) { // update client m_client.AdvanceTime(m_client.GetTime() + dt); m_client.ReceivePackets(); if (m_client.IsConnected()) { ProcessMessages(); // ... do connected stuff ... // send a message when space is pressed if (KeyIsDown(Key::SPACE)) { ``` -------------------------------- ### Game Server Fixed Timestep Game Loop Source: https://github.com/mas-bandwidth/yojimbo/blob/main/USAGE.md The server's main game loop runs at a fixed timestep to ensure consistent game state updates. It calculates the time elapsed and sleeps if necessary to maintain the target frame rate. ```cpp void GameServer::Run() { float fixedDt = 1.0f / 60.0f; while (m_running) { double currentTime = yojimbo_time(); if (m_time <= currentTime) { Update(fixedDt); m_time += fixedDt; } else { yojimbo_sleep(m_time - currentTime); } } } ``` -------------------------------- ### Test Matcher Endpoint with Curl Source: https://github.com/mas-bandwidth/yojimbo/blob/main/matcher/README.md Sends a test request to the matcher endpoint using curl. Replace PROTOCOL_ID and CLIENT_ID with your desired values. ```sh PROTOCOL_ID=123 && CLIENT_ID=42 && curl http://localhost:8081/match/${PROTOCOL_ID}/${CLIENT_ID} ``` -------------------------------- ### Game Server Message Processing Loop Source: https://github.com/mas-bandwidth/yojimbo/blob/main/USAGE.md This function iterates through all connected clients and their message channels to receive and process incoming messages. It handles messages one by one until no more are available for a given channel. ```cpp void GameServer::ProcessMessages() { for (int i = 0; i < MAX_PLAYERS; i++) { if (m_server.IsClientConnected(i)) { for (int j = 0; j < m_connectionConfig.numChannels; j++) { yojimbo::Message* message = m_server.ReceiveMessage(i, j); while (message != NULL) { ProcessMessage(i, message); m_server.ReleaseMessage(i, message); message = m_server.ReceiveMessage(i, j); } } } } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.