API Server Overview
Relevant source files
The following files were used as context for generating this wiki page:
The API Server is a core component of the mcpi-recompiled project, designed to provide a network-accessible interface compatible with the original Minecraft: Pi Edition 0.1.1 alpha programming API. Its primary purpose is to listen for incoming TCP connections on port 4711, parse text-based commands, and dispatch them to a handler that simulates or executes game logic.
Sources: README.md:9-14, src/api/ApiServer.hpp:16-20
This module facilitates cross-platform communication by using standard socket programming, supporting both modern Linux and Windows (x86-64) systems. It serves as the foundation for the project's goal of preserving compatibility with existing MCPI scripts and tools.
Sources: README.md:10-13, src/api/ApiServer.cpp:11-26
Architecture and Components
The API Server follows a PIMPL (Pointer to Implementation) idiom to hide networking details and platform-specific socket logic from the public interface.
The ApiServer Class
The ApiServer class manages the lifecycle of the TCP listener. It is non-copyable and non-movable to ensure stable ownership of the background worker thread.
Sources: src/api/ApiServer.hpp:16-26, src/api/ApiServer.cpp:142-146
Internal Implementation (Impl)
The Impl struct contains the core logic for the server, including the listener socket, the worker thread, and client handling routines. It utilizes an std::atomic<bool> to manage the server's running state across threads.
Sources: src/api/ApiServer.cpp:88-140
| Component | Description |
|---|---|
| Listener Socket | A TCP socket bound to the configured port (default 4711) that accepts incoming client connections. |
| Worker Thread | A background thread that executes the run() loop, blocking on accept() for new connections. |
| Handler | A functional callback (std::function) provided by the user to process parsed Command objects. |
| Command Parser | Logic within Command.cpp that transforms raw strings into structured Command objects. |
Sources: src/api/ApiServer.hpp:18-28, src/api/ApiServer.cpp:100-110, src/api/Command.hpp:13-17
Command Processing Flow
The server operates on a line-delimited protocol. It buffers incoming data from clients until a newline character (\n) is detected, at which point the line is processed.
Parsing Logic
The parser identifies the command name and its parenthesized arguments. For example, world.setBlock(1,2,3,1) is decomposed into a name (world.setBlock) and a list of arguments (["1", "2", "3", "1"]).
Sources: src/api/Command.cpp:32-60, tests/api_server_tests.cpp:103-107
This diagram illustrates the loop within handle_client where raw TCP streams are converted into discrete command executions.
Sources: src/api/ApiServer.cpp:111-140
Sequence of a Command Request
The following sequence diagram shows the interaction between a client, the ApiServer, and the registered Handler.
Socket Management and Platform Parity
The implementation provides a unified interface for Windows (Winsock2) and POSIX systems.
- Timeouts: Client sockets are configured with a 200ms receive timeout (
SO_RCVTIMEO) to allow the server to periodically check theis_runningflag and exit gracefully. - Port Selection: If initialized with port
0, the server binds to an ephemeral port, which can be queried viaport(). - Address Reuse: The
SO_REUSEADDRoption is set to allow immediate restarts of the server on the same port.
Sources: src/api/ApiServer.cpp:46-63, src/api/ApiServer.cpp:166-177, tests/api_server_tests.cpp:101-102
Configuration Defaults
| Parameter | Default Value | Description |
|---|---|---|
| Port | 4711 | Standard MCPI API port. |
| Buffer Size | 4096 bytes | Internal buffer for recv operations. |
| Listen Backlog | 4 | Number of pending connections allowed. |
| Receive Timeout | 200ms | Timeout for socket read operations. |
Sources: src/api/ApiServer.cpp:100, src/api/ApiServer.cpp:112, src/api/ApiServer.cpp:48-55, src/api/ApiServer.cpp:189
Command Structure
The Command structure is a simple data holder defined in Command.hpp.
// src/api/Command.hpp:13-16
struct Command {
std::string name;
std::vector<std::string> arguments;
};
The parser handles various edge cases, including:
- Zero-argument commands:
player.getPos()results in an empty arguments vector. - Malformed input: Strings without matching parentheses or trailing data are rejected.
- Whitespace: The parser trims leading/trailing whitespace from the command line and individual arguments.
Sources: src/api/Command.cpp:32-45, tests/protocol_tests.cpp:33-47
Conclusion
The API Server module provides a robust, cross-platform implementation of the Minecraft: Pi Edition protocol. By abstracting socket management and providing a structured command parsing pipeline, it allows the rest of the project to focus on reconstructing game systems while maintaining full compatibility with the original 0.1.1 alpha API.
Sources: README.md:10-15, src/api/ApiServer.cpp:208-212