mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-06-10 05:03:29 -04:00
b61db77020
also unique_ptr
166 lines
4.7 KiB
C++
166 lines
4.7 KiB
C++
#include "Network.h"
|
|
#include <spdlog/spdlog.h>
|
|
#include <libultraship/libultraship.h>
|
|
|
|
// MARK: - Public
|
|
|
|
void Network::Enable(const char* host, uint16_t port) {
|
|
#ifdef ENABLE_REMOTE_CONTROL
|
|
if (isEnabled) {
|
|
return;
|
|
}
|
|
|
|
if (SDLNet_ResolveHost(&networkAddress, host, port) == -1) {
|
|
SPDLOG_ERROR("[Network] SDLNet_ResolveHost: {}", SDLNet_GetError());
|
|
}
|
|
|
|
isEnabled = true;
|
|
|
|
// First check if there is a thread running, if so, join it
|
|
if (receiveThread.joinable()) {
|
|
receiveThread.join();
|
|
}
|
|
|
|
receiveThread = std::thread(&Network::ReceiveFromServer, this);
|
|
#endif
|
|
}
|
|
|
|
void Network::Disable() {
|
|
if (!isEnabled) {
|
|
return;
|
|
}
|
|
|
|
isEnabled = false;
|
|
receiveThread.join();
|
|
}
|
|
|
|
void Network::OnIncomingData(char payload[512]) {
|
|
}
|
|
|
|
void Network::OnIncomingJson(nlohmann::json payload) {
|
|
}
|
|
|
|
void Network::OnConnected() {
|
|
}
|
|
|
|
void Network::OnDisconnected() {
|
|
}
|
|
|
|
void Network::ProcessOutgoingPackets() {
|
|
}
|
|
|
|
void Network::SendDataToRemote(const char* payload) {
|
|
#ifdef ENABLE_REMOTE_CONTROL
|
|
SPDLOG_DEBUG("[Network] Sending data: {}", payload);
|
|
SDLNet_TCP_Send(networkSocket, payload, strlen(payload) + 1);
|
|
#endif
|
|
}
|
|
|
|
void Network::SendJsonToRemote(nlohmann::json payload) {
|
|
SendDataToRemote(payload.dump().c_str());
|
|
}
|
|
|
|
// MARK: - Private
|
|
|
|
void Network::ReceiveFromServer() {
|
|
#ifdef ENABLE_REMOTE_CONTROL
|
|
while (isEnabled) {
|
|
while (!isConnected && isEnabled) {
|
|
SPDLOG_TRACE("[Network] Attempting to make connection to server...");
|
|
networkSocket = SDLNet_TCP_Open(&networkAddress);
|
|
|
|
if (networkSocket) {
|
|
isConnected = true;
|
|
receivedData.clear();
|
|
SPDLOG_INFO("[Network] Connection to server established!");
|
|
|
|
OnConnected();
|
|
break;
|
|
}
|
|
}
|
|
|
|
SDLNet_SocketSet socketSet = SDLNet_AllocSocketSet(1);
|
|
if (networkSocket) {
|
|
SDLNet_TCP_AddSocket(socketSet, networkSocket);
|
|
}
|
|
|
|
// Listen to socket messages
|
|
while (isConnected && networkSocket && isEnabled) {
|
|
// we check first if socket has data, to not block in the TCP_Recv
|
|
int socketsReady = SDLNet_CheckSockets(socketSet, 0);
|
|
|
|
if (socketsReady == -1) {
|
|
SPDLOG_ERROR("[Network] SDLNet_CheckSockets: {}", SDLNet_GetError());
|
|
break;
|
|
}
|
|
|
|
// Always process outgoing packets
|
|
ProcessOutgoingPackets();
|
|
|
|
if (socketsReady == 0) {
|
|
// No incoming data
|
|
continue;
|
|
}
|
|
|
|
char remoteDataReceived[512];
|
|
memset(remoteDataReceived, 0, sizeof(remoteDataReceived));
|
|
int len = SDLNet_TCP_Recv(networkSocket, &remoteDataReceived, sizeof(remoteDataReceived));
|
|
if (!len || !networkSocket || len == -1) {
|
|
SPDLOG_ERROR("[Network] SDLNet_TCP_Recv: {}", SDLNet_GetError());
|
|
break;
|
|
}
|
|
|
|
HandleRemoteData(remoteDataReceived);
|
|
|
|
receivedData.append(remoteDataReceived, len);
|
|
|
|
// Proess all complete packets
|
|
size_t delimiterPos = receivedData.find('\0');
|
|
while (delimiterPos != std::string::npos) {
|
|
// Extract the complete packet until the delimiter
|
|
std::string packet = receivedData.substr(0, delimiterPos);
|
|
// Remove the packet (including the delimiter) from the received data
|
|
receivedData.erase(0, delimiterPos + 1);
|
|
HandleRemoteJson(packet);
|
|
// Find the next delimiter
|
|
delimiterPos = receivedData.find('\0');
|
|
}
|
|
}
|
|
|
|
if (socketSet) {
|
|
SDLNet_FreeSocketSet(socketSet);
|
|
}
|
|
|
|
if (isConnected) {
|
|
SDLNet_TCP_Close(networkSocket);
|
|
networkSocket = nullptr;
|
|
isConnected = false;
|
|
receivedData.clear();
|
|
OnDisconnected();
|
|
SPDLOG_INFO("[Network] Ending receiving thread...");
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void Network::HandleRemoteData(char payload[512]) {
|
|
OnIncomingData(payload);
|
|
}
|
|
|
|
void Network::HandleRemoteJson(std::string payload) {
|
|
SPDLOG_DEBUG("[Network] Received json: {}", payload);
|
|
nlohmann::json jsonPayload;
|
|
try {
|
|
jsonPayload = nlohmann::json::parse(payload);
|
|
} catch (const std::exception& e) {
|
|
SPDLOG_ERROR("[Network] Failed to parse json: \n{}\n{}\n", payload, e.what());
|
|
return;
|
|
}
|
|
|
|
try {
|
|
OnIncomingJson(jsonPayload);
|
|
} catch (const std::exception& e) {
|
|
SPDLOG_ERROR("[Network] Exception handling incoming JSON: {}", e.what());
|
|
} catch (...) { SPDLOG_ERROR("[Network] Unknown exception handling incoming JSON"); }
|
|
}
|