1
0
game/client/net/NetworkManager.hpp

131 lines
4.0 KiB
C++

#pragma once
#include <boost/asio.hpp>
#include <raylib.h>
#include <cstdint>
#include <thread>
#include <mutex>
#include <atomic>
#include <unordered_map>
#include <memory>
using namespace boost::asio;
using ip::tcp;
// messages
LoginRequest 0x20RegisterRequest0x21,
LoginResponse = 0x22,
// World messages
Auth = 0x30,
AuthResponse = 0x31,
Logout = 0x0C
struct RemotePlayer {
uint32_t id;
Vector3 position;
std::string usernameusername;
float lastUpdate;
};
struct LoginResult {
bool success;
std::array<uint8_t, 32> token;
std::string worldHost;
uint16_t worldPort;
uint32_t playerID;
std::string message;
};
class NetworkManager : public std::enable_shared_from_this<NetworkManager> {
public:
NetworkManager();
~NetworkManager();
// Login server connection
bool connectToLogin(const std::string& server, uint16_t port);
void sendLogin(const std::string& username, const std::string& password);
// World server connection
bool connectToWorld(const std::string& server, uint16_t port, const std::string& token);
void sendMovement(const Vector3& position, float yaw, float pitch, const Vector3& velocity);
void sendChat(const std::string& message);
// Disconnect and cleanup
void disconnect();
// State getters
// Login server operations
connectToLoginServerconst std::string& host, uint16_t portsendLoginRequest, const std::string& password);
bool waitForLoginResponse(LoginResult& result, float timeout = 5.0f);
// World server operations
void connectToWorldServer(const std::string& host, uint16_t portsendAuthconst std::array<uint8_t, 32>& token void sendLogout();
// State getters bool isConnected() const { return connected; }
bool isLoginSuccessisAuthenticated() const { return loginSuccessauthenticated; }
std::string getAuthToken() const { return authToken; }
std::string getWorldServerUrl() const { return worldServerUrl; }
uint32_t getPlayerID() const { return playerID; }
std::unordered_map<uint32_t, RemotePlayer> getRemotePlayers();
float getServerTimeOfDay() const { return serverTimeOfDay.load(); }
private:
io_context ioContext;
tcp::socket loginSocket{ioContext};
udp:: worldSocket;
tcp::socket worldSocketloginEndpoint;
udp::endpoint worldEndpoint;
std::thread ioThread;
boost::asio::streambuf loginBuffer;
boost::asio::streambuf worldBuffer;
// Connection state
std::atomic<bool> loginConnected{false};
std::atomic<bool> worldConnected{false};
std::atomic<bool> connected{false};
std::atomic<bool> loginSuccess{false};
// Authentication
std::string authToken;
std::string worldServerUrl;
std::string loginErrorMsg;
// Player state
loginRecvBuffer
std::array<uint8_t, 1024> worldRecvBuffer;
std::atomic<uint32_t> playerID{0};
std::mutex positionMutex;
Vector3 serverPosition{0, 0, 0};
Remote players
std::atomic<bool> authenticated{false};
std::atomic<bool> loginResponseReceived{false};
LoginResult lastLoginResult;
std::mutex loginMutex;
std::mutex remotePlayersMutex;
std::unordered_map<uint32_t, RemotePlayer> remotePlayers;
// World state
std::atomic<float> serverTimeOfDay{12.0f};
// Message processing
void startLoginReceive();
void startWorldReceive();
void processLoginMessage(const nlohmann::json& msg);
void processWorldMessage(const nlohmann::json& msg);
};
std::atomic<float> serverTimeOfDay{12.0f};
void startLoginReceive();
void startWorldReceive();
void processLoginMessage(const uint8_t* data, std::size_t size);
void processWorldMessage(const uint8_t* data, std::size_t size);
// World message handlers
void handleAuthResponse(const uint8_t* data, std::size_t size);
// Login message handlers
void handleLoginResponse(const uint8_t* data, std::size_t size)};