Files
meteorbot-old/bot/external/Botcraft/tests/botcraft_online/include/MinecraftServer.hpp
T

82 lines
2.7 KiB
C++
Raw Normal View History

2024-04-30 22:07:50 -06:00
#pragma once
#include <thread>
#include <mutex>
#include <queue>
#include <string>
#include <memory>
#include <vector>
#include <filesystem>
struct subprocess_s;
struct MinecraftServerOptions
{
std::string argv0 = "";
int view_distance = 5;
};
/// @brief Singleton wrapper around a Minecraft server subprocess instance.
/// Built to be used in a single-threaded way (to follow catch2 requirements).
class MinecraftServer
{
private:
MinecraftServer();
~MinecraftServer();
MinecraftServer(const MinecraftServer&) = delete;
MinecraftServer(MinecraftServer&&) = delete;
MinecraftServer& operator=(const MinecraftServer&) = delete;
public:
static MinecraftServerOptions options;
static MinecraftServer& GetInstance();
void Initialize();
/// @brief Wait for the subprocess to write a line to stdout or stderr. Thread safe
/// @param timeout_ms If != 0 and no line received after timeout_ms, will throw an exception
/// @return The received line content
std::string WaitLine(const long long int timeout_ms = 0);
/// @brief Wait for the subprocess to write a line matching regex to stdout or stderr.
/// @param regex A regex pattern of the line to match
/// @param timeout_ms If != 0 and no matching line received after timeout_ms, will throw an exception
/// @return First element is the full line, other are all the captured groups from the regex
std::vector<std::string> WaitLine(const std::string& regex, const long long int timeout_ms = 0);
/// @brief Write a line to subprocess stdin. Not thread-safe.
/// @param input Line to write
void SendLine(const std::string& input);
/// @brief Path to the folder holding the structure files
/// @return The path in which the server loads the structures
std::filesystem::path GetStructurePath() const;
private:
/// @brief Terminate the subprocess
void Kill();
/// @brief Internal function used to retrieve stdout and stderr
void InternalThreadRead();
/// @brief Prepare a folder to host a server
void InitServerFolder(const std::filesystem::path& path);
/// @brief Set a gamerule value on the server
void SetGamerule(const std::string& gamerule, const std::string& value);
/// @brief Set all non default gamerules on the server
void InitServerGamerules();
private:
/// @brief Thread running the stdout reading loop
std::thread read_thread;
/// @brief Internal mutex for the std::queue lines
std::mutex internal_read_mutex;
/// @brief Queue of lines generated by the subprocess
std::queue<std::string> lines;
/// @brief Server subprocess handle
std::unique_ptr<subprocess_s> subprocess;
bool running;
std::filesystem::path server_path;
};