90 lines
2.5 KiB
C++
90 lines
2.5 KiB
C++
#pragma once
|
|
|
|
#include <boost/asio.hpp>
|
|
#include <raylib.h>
|
|
#include <cstdint>
|
|
#include <thread>
|
|
#include <mutex>
|
|
#include <atomic>
|
|
#include <unordered_map>
|
|
#include <array>
|
|
|
|
using namespace boost::asio;
|
|
using ip::udp;
|
|
|
|
enum class MessageType : uint8_t {
|
|
Login = 0x01,
|
|
Position = 0x02,
|
|
Spawn = 0x03,
|
|
Move = 0x04,
|
|
Update = 0x05,
|
|
PlayerJoined = 0x06,
|
|
PlayerLeft = 0x07,
|
|
PlayerList = 0x08,
|
|
ChangeColor = 0x09,
|
|
ColorChanged = 0x0A,
|
|
LoginResponse = 0x0B,
|
|
Logout = 0x0C,
|
|
Heartbeat = 0x0D
|
|
};
|
|
|
|
struct RemotePlayer {
|
|
uint32_t id;
|
|
Vector3 position;
|
|
std::string color;
|
|
float lastUpdate;
|
|
};
|
|
|
|
class NetworkManager {
|
|
public:
|
|
NetworkManager();
|
|
~NetworkManager();
|
|
|
|
void sendLogin();
|
|
void sendLoginWithUsername(const std::string& username);
|
|
void sendLogout();
|
|
void sendMove(float dx, float dy, float dz);
|
|
void sendColorChange(const std::string& newColor);
|
|
void sendHeartbeat();
|
|
|
|
Vector3 getPosition();
|
|
bool isConnected() const { return connected; }
|
|
bool hasLoginError() const { return !loginErrorMsg.empty(); }
|
|
std::string getLoginError() const { return loginErrorMsg; }
|
|
uint32_t getPlayerID() const { return playerID; }
|
|
std::string getPlayerColor() const { return playerColor; }
|
|
|
|
std::unordered_map<uint32_t, RemotePlayer> getRemotePlayers();
|
|
|
|
// Available colors for cycling
|
|
static const std::vector<std::string> AVAILABLE_COLORS;
|
|
|
|
private:
|
|
io_context ioContext;
|
|
udp::socket socket{ioContext};
|
|
udp::endpoint serverEndpoint;
|
|
std::thread ioThread;
|
|
std::array<uint8_t, 1024> recvBuffer;
|
|
|
|
std::atomic<uint32_t> playerID{0};
|
|
std::string playerColor{"red"};
|
|
std::string currentUsername{""};
|
|
std::string loginErrorMsg{""};
|
|
std::mutex positionMutex;
|
|
Vector3 serverPosition{0, 0, 0};
|
|
std::atomic<bool> connected{false};
|
|
|
|
std::mutex remotePlayersMutex;
|
|
std::unordered_map<uint32_t, RemotePlayer> remotePlayers;
|
|
|
|
void startReceive();
|
|
void processMessage(const uint8_t* data, std::size_t size);
|
|
void handleSpawn(const uint8_t* data, std::size_t size);
|
|
void handleUpdate(const uint8_t* data, std::size_t size);
|
|
void handlePlayerJoined(const uint8_t* data, std::size_t size);
|
|
void handlePlayerLeft(const uint8_t* data, std::size_t size);
|
|
void handlePlayerList(const uint8_t* data, std::size_t size);
|
|
void handleColorChanged(const uint8_t* data, std::size_t size);
|
|
void handleLoginResponse(const uint8_t* data, std::size_t size);
|
|
};
|