This commit is contained in:
2026-05-02 16:40:21 +10:00
parent 8d01ea4a3c
commit 1a4c33b9dc
23 changed files with 3725 additions and 401 deletions

View File

@@ -0,0 +1,68 @@
#pragma once
#include <winsock2.h>
#include <atomic>
#include <filesystem>
#include <functional>
#include <mutex>
#include <string>
#include <thread>
#include <vector>
class ControlServer
{
public:
struct Callbacks
{
std::function<std::string()> getStateJson;
std::function<bool(const std::string&, std::string&)> selectShader;
std::function<bool(const std::string&, const std::string&, const std::string&, std::string&)> updateParameter;
std::function<bool(bool, std::string&)> setBypass;
std::function<bool(double, std::string&)> setMixAmount;
std::function<bool(std::string&)> reloadShader;
};
ControlServer();
~ControlServer();
bool Start(const std::filesystem::path& uiRoot, unsigned short preferredPort, const Callbacks& callbacks, std::string& error);
void Stop();
void BroadcastState();
unsigned short GetPort() const { return mPort; }
private:
struct ClientConnection
{
SOCKET socket = INVALID_SOCKET;
bool websocket = false;
};
void ServerLoop();
bool HandleHttpClient(SOCKET clientSocket);
bool TryAcceptClient();
bool SendHttpResponse(SOCKET clientSocket, const std::string& status, const std::string& contentType, const std::string& body);
bool HandleHttpRequest(SOCKET clientSocket, const std::string& request);
bool HandleWebSocketUpgrade(SOCKET clientSocket, const std::string& request);
bool SendWebSocketText(SOCKET clientSocket, const std::string& payload);
void BroadcastStateLocked();
std::string LoadUiAsset(const std::string& relativePath, std::string& contentType) const;
std::string BuildJsonResponse(bool success, const std::string& error = std::string()) const;
static std::string Base64Encode(const unsigned char* data, DWORD dataLength);
static std::string ComputeWebSocketAcceptKey(const std::string& clientKey);
static std::string GetHeaderValue(const std::string& request, const std::string& headerName);
static std::string GetRequestPath(const std::string& request);
static std::string GetRequestMethod(const std::string& request);
static std::string GetRequestBody(const std::string& request);
private:
std::filesystem::path mUiRoot;
Callbacks mCallbacks;
SOCKET mListenSocket;
unsigned short mPort;
std::thread mThread;
std::atomic<bool> mRunning;
mutable std::mutex mMutex;
std::vector<ClientConnection> mClients;
};