diff --git a/SQCSim-common/SQCSim-common.vcxproj b/SQCSim-common/SQCSim-common.vcxproj index 5db21d0..15265fb 100644 --- a/SQCSim-common/SQCSim-common.vcxproj +++ b/SQCSim-common/SQCSim-common.vcxproj @@ -137,6 +137,7 @@ + @@ -144,6 +145,7 @@ + diff --git a/SQCSim-common/SQCSim-common.vcxproj.filters b/SQCSim-common/SQCSim-common.vcxproj.filters index af8b625..a98dd18 100644 --- a/SQCSim-common/SQCSim-common.vcxproj.filters +++ b/SQCSim-common/SQCSim-common.vcxproj.filters @@ -48,6 +48,9 @@ Fichiers d%27en-tête + + Fichiers d%27en-tête + @@ -68,5 +71,8 @@ Fichiers sources + + Fichiers sources + \ No newline at end of file diff --git a/SQCSim-common/define.h b/SQCSim-common/define.h index 3501dd6..968b71d 100644 --- a/SQCSim-common/define.h +++ b/SQCSim-common/define.h @@ -2,51 +2,55 @@ #define DEFINE_H__ #include - -#define CHUNK_SIZE_X 16 -#define CHUNK_SIZE_Y 128 -#define CHUNK_SIZE_Z 16 -#define MAX_SELECTION_DISTANCE 5 -#define SEED 12345 +#include #define SRV_PORT 1025 #define CLI_PORT 1026 -#ifdef _DEBUG +#define CHUNK_SIZE_X 4 +#define CHUNK_SIZE_Y 64 +#define CHUNK_SIZE_Z 4 +#define MAX_SELECTION_DISTANCE 5 +#define SEED 12345 +#define COUNTDOWN 300 + #define WORLD_SIZE_X 64 #define WORLD_SIZE_Y 64 -#define FRAMES_RENDER_CHUNKS 4 -#define FRAMES_UPDATE_CHUNKS 4 -#define FRAMES_DELETE_CHUNKS 4 - -#define THREADS_GENERATE_CHUNKS 1 -#define THREADS_UPDATE_CHUNKS 1 -#define THREADS_DELETE_CHUNKS 1 - -#define VIEW_DISTANCE 256 -#define TEXTURE_SIZE 128 -#define MAX_BULLETS 64 -#endif - -#ifdef NDEBUG -#define WORLD_SIZE_X 16 -#define WORLD_SIZE_Y 16 - -#define FRAMES_RENDER_CHUNKS 1 -#define FRAMES_UPDATE_CHUNKS 1 -#define FRAMES_DELETE_CHUNKS 1 - -#define THREADS_GENERATE_CHUNKS 12 -#define THREADS_UPDATE_CHUNKS 5 -#define THREADS_DELETE_CHUNKS 2 - -#define VIEW_DISTANCE 1024 +#define VIEW_DISTANCE 512 #define TEXTURE_SIZE 512 #define MAX_BULLETS 512 -#endif typedef uint8_t BlockType; enum BLOCK_TYPE { BTYPE_AIR, BTYPE_DIRT, BTYPE_GRASS, BTYPE_METAL, BTYPE_ICE, BTYPE_LAST }; +typedef uint64_t Timestamp; + +#ifdef _WIN32 + +#pragma comment(lib,"wsock32.lib") // Pour pouvoir faire fonctionner le linker sans le vcxproject +#pragma comment(lib,"ws2_32.lib") +#include +#include +#include +#include + +#define popen _popen +#define pclose _pclose + +#else // Pas _WIN32 + +#include +#include +#include +#include +#include +#include + +#define SOCKET int +#define INVALID_SOCKET -1 +#define closesocket close + +#endif // _WIN32 + #endif // DEFINE_H__ diff --git a/SQCSim-common/netprotocol.cpp b/SQCSim-common/netprotocol.cpp new file mode 100644 index 0000000..d7f7675 --- /dev/null +++ b/SQCSim-common/netprotocol.cpp @@ -0,0 +1,230 @@ +#include "netprotocol.h" + +void netprot::Serialize(Input* in, char* buf[], uint32_t* buflen) { + +} + +void netprot::Serialize(Output* out, char* buf[], uint32_t* buflen) { + +} + +void netprot::Serialize(Sync* sync, char* buf[], uint32_t* buflen) { + +} + +void netprot::Serialize(TeamInfo* tinfo, char* buf[], uint32_t* buflen) { + +} + +void netprot::Serialize(LoginInfo* linfo, char* buf[], uint32_t* buflen) { + *buf[0] = netprot::PACKET_TYPE::LOGINF; + + size_t namesize = std::strlen(linfo->name) + 1; + + memcpy(*buf + 1, &linfo->name, namesize); + uint64_t sid = linfo->sid; + uint8_t sid8[sizeof(uint64_t)] = { + (sid >> 56) & 0xFF, + (sid >> 48) & 0xFF, + (sid >> 40) & 0xFF, + (sid >> 32) & 0xFF, + (sid >> 24) & 0xFF, + (sid >> 16) & 0xFF, + (sid >> 8) & 0xFF, + sid & 0xFF + }; + + memcpy(*buf + namesize + 2, sid8, sizeof(uint64_t)); + + uint64_t tid = linfo->tid; + uint8_t tid8[sizeof(uint64_t)] = { + (tid >> 56) & 0xFF, + (tid >> 48) & 0xFF, + (tid >> 40) & 0xFF, + (tid >> 32) & 0xFF, + (tid >> 24) & 0xFF, + (tid >> 16) & 0xFF, + (tid >> 8) & 0xFF, + tid & 0xFF + }; + + memcpy(*buf + namesize + 2 + sizeof(uint64_t), tid8, sizeof(uint64_t)); + + *buflen = namesize + sizeof(uint64_t) * 2 + 2; +} + +void netprot::Serialize(PlayerInfo* pinfo, char* buf[], uint32_t* buflen) { + +} + +void netprot::Serialize(GameInfo* ginfo, char* buf[], uint32_t* buflen) { + *buf[0] = netprot::PACKET_TYPE::GAMEINFO; + + uint64_t game = ginfo->seed; + uint8_t seed8[sizeof(uint64_t)] = { + (game >> 56) & 0xFF, + (game >> 48) & 0xFF, + (game >> 40) & 0xFF, + (game >> 32) & 0xFF, + (game >> 24) & 0xFF, + (game >> 16) & 0xFF, + (game >> 8) & 0xFF, + game & 0xFF + }; + + memcpy(*buf + 1, seed8, sizeof(uint64_t)); + + game = ginfo->countdown; + uint8_t count8[sizeof(uint64_t)] = { + (game >> 56) & 0xFF, + (game >> 48) & 0xFF, + (game >> 40) & 0xFF, + (game >> 32) & 0xFF, + (game >> 24) & 0xFF, + (game >> 16) & 0xFF, + (game >> 8) & 0xFF, + game & 0xFF + }; + + memcpy(*buf + sizeof(uint64_t) + 1, count8, sizeof(uint64_t)); + + game = ginfo->countdown; + uint8_t gtype8[sizeof(uint64_t)] = { + (game >> 56) & 0xFF, + (game >> 48) & 0xFF, + (game >> 40) & 0xFF, + (game >> 32) & 0xFF, + (game >> 24) & 0xFF, + (game >> 16) & 0xFF, + (game >> 8) & 0xFF, + game & 0xFF + }; + + memcpy(*buf + sizeof(uint64_t) + 1, gtype8, sizeof(uint64_t)); + + *buflen = sizeof(uint64_t) * 3 + 1; +} + +void netprot::Serialize(Chat* chat, char* buf[], uint32_t* buflen) { + +} + +void netprot::Serialize(ErrorLog* errlog, char* buf[], uint32_t* buflen) { + +} + + + +bool netprot::Deserialize(Input* in, char* buf, const uint32_t buflen) { + return false; +} + +bool netprot::Deserialize(Output* out, char* buf, const uint32_t buflen) { + return false; +} + +bool netprot::Deserialize(Sync* sync, char* buf, const uint32_t buflen) { + return false; +} + +bool netprot::Deserialize(TeamInfo* tinfo, char* buf, const uint32_t buflen) { + return false; +} + +bool netprot::Deserialize(LoginInfo* linfo, char* buf, const uint32_t buflen) { + if (buflen < sizeof(LoginInfo) + 3) + return false; + + size_t namesize = std::strlen(buf) + 1; + + if (namesize > 32) + return false; + + memcpy(&linfo->name, &buf[1], namesize); + + uint8_t diff[sizeof(uint64_t)] = { 0,0,0,0,0,0,0,0 }; + memcpy(diff, &buf[namesize + 1], sizeof(uint64_t)); + linfo->sid = + (uint64_t)diff[0] << 56 | + (uint64_t)diff[1] << 48 | + (uint64_t)diff[2] << 40 | + (uint64_t)diff[3] << 32 | + (uint64_t)diff[4] << 24 | + (uint64_t)diff[5] << 16 | + (uint64_t)diff[6] << 8 | + (uint64_t)diff[7]; + + memcpy(diff, &buf[namesize + sizeof(uint64_t) + 1], sizeof(uint64_t)); + linfo->tid = + (uint64_t)diff[0] << 56 | + (uint64_t)diff[1] << 48 | + (uint64_t)diff[2] << 40 | + (uint64_t)diff[3] << 32 | + (uint64_t)diff[4] << 24 | + (uint64_t)diff[5] << 16 | + (uint64_t)diff[6] << 8 | + (uint64_t)diff[7]; + + return true; +} + +bool netprot::Deserialize(PlayerInfo* pinfo, char* buf, const uint32_t buflen) { + return false; +} + +bool netprot::Deserialize(GameInfo* ginfo, char* buf, const uint32_t buflen) { + if (buflen < sizeof(GameInfo) + 1) + return false; + + uint8_t diff[sizeof(uint64_t)] = { 0,0,0,0,0,0,0,0 }; + memcpy(diff, &buf[1], sizeof(uint64_t)); + ginfo->seed = + (uint64_t)diff[0] << 56 | + (uint64_t)diff[1] << 48 | + (uint64_t)diff[2] << 40 | + (uint64_t)diff[3] << 32 | + (uint64_t)diff[4] << 24 | + (uint64_t)diff[5] << 16 | + (uint64_t)diff[6] << 8 | + (uint64_t)diff[7]; + + memcpy(diff, &buf[sizeof(uint64_t) + 1], sizeof(uint64_t)); + ginfo->countdown = + (uint64_t)diff[0] << 56 | + (uint64_t)diff[1] << 48 | + (uint64_t)diff[2] << 40 | + (uint64_t)diff[3] << 32 | + (uint64_t)diff[4] << 24 | + (uint64_t)diff[5] << 16 | + (uint64_t)diff[6] << 8 | + (uint64_t)diff[7]; + + memcpy(diff, &buf[sizeof(uint64_t) * 2 + 1], sizeof(uint64_t)); + ginfo->gameType = + (uint64_t)diff[0] << 56 | + (uint64_t)diff[1] << 48 | + (uint64_t)diff[2] << 40 | + (uint64_t)diff[3] << 32 | + (uint64_t)diff[4] << 24 | + (uint64_t)diff[5] << 16 | + (uint64_t)diff[6] << 8 | + (uint64_t)diff[7]; + + return true; +} + +bool netprot::Deserialize(Chat* chat, char* buf, const uint32_t buflen) { + return false; +} + +bool netprot::Deserialize(ErrorLog* errlog, char* buf, const uint32_t buflen) { + return false; +} + +netprot::PacketType netprot::getType(char* buf, const uint32_t buflen) { + if (buflen < 1 || + buf[0] >= netprot::PACKET_TYPE::LAST_PACK || + buf[0] <= netprot::PACKET_TYPE::ERR) + return netprot::PACKET_TYPE::ERR; + return buf[0]; +} diff --git a/SQCSim-common/netprotocol.h b/SQCSim-common/netprotocol.h new file mode 100644 index 0000000..3e237f7 --- /dev/null +++ b/SQCSim-common/netprotocol.h @@ -0,0 +1,101 @@ +#ifndef NETPROTOCOL_H__ +#define NETPROTOCOL_H__ +#include "define.h" +#include +#include "vector3.h" + +/* Protocole Particulier de Partie à Plusieurs Personnes (PPPPP) */ + +// Packet: packet[0] = PacketType, packet[1..n-1] = {packet} + +namespace netprot { + typedef uint8_t PacketType; + enum PACKET_TYPE { + ERR, INPUT, OUTPUT, SYNC, + TEAMINF, SELFINF, PLAYINF, LOGINF, + CHUNKMOD, PLAYERMOD, PICKUPMOD, + GAMEINFO, ENDINFO , CHAT, ERRLOG, + LAST_PACK + }; + + struct Input { // cli -> srv UDP ~frame + Timestamp timestamp; + uint8_t keys; // 0bFBLRJS__ bit-packing de bool. + Vector3f direction; + }; + + struct Output { // srv -> cli UDP ~frame + Timestamp timestamp; + uint64_t id = 0; + Vector3f position, + direction; + uint8_t states; // 0bJSH_____ bit-packing de bool. + }; + + struct Sync { // srv -> cli TCP ~second + Timestamp timestamp; + uint64_t sid = 0; + uint32_t timer = 0; + uint16_t ammo = 0; + uint8_t hp = 0; + Vector3f position; + }; + + struct TeamInfo { // cli <-> srv TCP once + char name[32]; + uint64_t id = 0; + }; + + struct LoginInfo { // cli <-> srv TCP once + char name[32]; + uint64_t sid = 0, + tid = 0; + }; + + struct PlayerInfo { // cli <-> srv TCP once + char name[32]; + uint64_t id = 0, + tid = 0; + }; + + struct GameInfo { // cli <-> srv TCP event (before game start)/ once + uint64_t seed; + uint32_t countdown; + uint8_t gameType; // TOOD: enum. + }; + + struct Chat { // cli <-> srv TCP event + uint64_t src_id = 0, + dest_id = 0, + dest_team_id = 0; + char mess[140]; // Good 'nough for twitr, good 'nough for me. + }; + + struct ErrorLog { // srv -> cli TCP event + char mess[140]; + bool is_fatal; + }; + + void Serialize(Input* in, char* buf[], uint32_t* buflen); // cli + void Serialize(Output* out, char* buf[], uint32_t* buflen); // srv + void Serialize(Sync* sync, char* buf[], uint32_t* buflen); // srv + void Serialize(TeamInfo* tinfo, char* buf[], uint32_t* buflen); // cli/srv + void Serialize(LoginInfo* linfo, char* buf[], uint32_t* buflen); // cli/srv + void Serialize(PlayerInfo* pinfo, char* buf[], uint32_t* buflen); // srv + void Serialize(GameInfo* ginfo, char* buf[], uint32_t* buflen); // cli/srv + void Serialize(Chat* chat, char* buf[], uint32_t* buflen); // cli/srv + void Serialize(ErrorLog* errlog, char* buf[], uint32_t* buflen); // srv + + bool Deserialize(Input* in, char* buf, const uint32_t buflen); // srv + bool Deserialize(Output* out, char* buf, const uint32_t buflen); // cli + bool Deserialize(Sync* sync, char* buf, const uint32_t buflen); // cli + bool Deserialize(TeamInfo* tinfo, char* buf, const uint32_t buflen); // cli/srv + bool Deserialize(LoginInfo* linfo, char* buf, const uint32_t buflen); // cli/srv + bool Deserialize(PlayerInfo* pinfo, char* buf, const uint32_t buflen); // cli + bool Deserialize(GameInfo* ginfo, char* buf, const uint32_t buflen); // cli + bool Deserialize(Chat* chat, char* buf, const uint32_t buflen); // srv/cli + bool Deserialize(ErrorLog* errlog, char* buf, const uint32_t buflen); // srv + + PacketType getType(char* buf, uint32_t buflen); // srv/cli +} +#endif diff --git a/SQCSim-srv/connection.cpp b/SQCSim-srv/connection.cpp index 2b93114..356396f 100644 --- a/SQCSim-srv/connection.cpp +++ b/SQCSim-srv/connection.cpp @@ -1,48 +1,46 @@ #include "connection.h" -Connection::Connection(in_addr addr, - std::string name, - UINT64 id, - UINT64 self_id, - UINT64 team_id): - m_addr(addr), - m_id(id), - m_sid(self_id), - m_tid(team_id), - m_name(name) { + + +Connection::Connection(SOCKET sock, + sockaddr_in sockaddr, + netprot::LoginInfo log, + netprot::PlayerInfo play): + m_sock(sock), + m_addr(sockaddr), + m_loginfo(log), + m_playinfo(play) { } Connection::~Connection() { - + closesocket(m_sock); } -in_addr Connection::GetAddr() const { return m_addr; } +uint64_t Connection::GetHash(bool self) const { return self? m_loginfo.sid: m_playinfo.id; } -UINT64 Connection::GetHash(bool self) const { return self? m_sid: m_id; } +uint64_t Connection::GetTeamHash() const { return m_loginfo.tid; } -UINT64 Connection::GetTeamHash() const { return m_tid; } +std::string Connection::GetName() const { return m_loginfo.name; } -std::string Connection::GetName() const { return m_name; } - -void Connection::AddInput(Input in) { - m_input_manifest.insert({in.timestamp, in}); +void Connection::AddInput(netprot::Input in) { + m_input_manifest.insert({ in.timestamp, in }); } -Output* Connection::getOutput(Timestamp time) { +netprot::Output* Connection::getOutput(Timestamp time) { auto out = m_output_manifest.find(time); if (out != m_output_manifest.end()) return &out->second; return nullptr; } -Sync Connection::getSync(Timestamp time) { - Sync sync; +netprot::Sync Connection::getSync(Timestamp time) { + netprot::Sync sync; auto out = m_output_manifest.find(time); if (out != m_output_manifest.end()) { sync.timestamp = out->second.timestamp; sync.position = out->second.position; - sync.sid = m_sid; + sync.sid = m_loginfo.sid; } return sync; } diff --git a/SQCSim-srv/connection.h b/SQCSim-srv/connection.h index 5b0134d..dc1df11 100644 --- a/SQCSim-srv/connection.h +++ b/SQCSim-srv/connection.h @@ -4,57 +4,38 @@ #include #include "../SQCSim-common/player.h" #include "../SQCSim-common/vector3.h" +#include "../SQCSim-common/netprotocol.h" #include "define.h" -struct Input { - Timestamp timestamp; - UINT8 keys; // 0bFBLRJS__ - Vector3f direction; -}; - -struct Output { - Timestamp timestamp; - UINT64 id = 0; - Vector3f position, direction; - bool is_shooting, is_jumping; -}; - -struct Sync { - Timestamp timestamp; - UINT64 sid = 0; - Vector3f position; -}; - class Connection { public: Connection( - in_addr addr, - std::string name, - UINT64 hash, - UINT64 self_hash, - UINT64 team_hash); + SOCKET sock, + sockaddr_in sockaddr, + netprot::LoginInfo log, + netprot::PlayerInfo play); ~Connection(); Player* player = nullptr; - in_addr GetAddr() const; - UINT64 GetHash(bool self = true) const; - UINT64 GetTeamHash() const; + uint64_t GetHash(bool self = true) const; + uint64_t GetTeamHash() const; std::string GetName() const; - void AddInput(Input in); - Output* getOutput(Timestamp time); - Sync getSync(Timestamp time); + void AddInput(netprot::Input in); + netprot::Output* getOutput(Timestamp time); + netprot::Sync getSync(Timestamp time); void CleanInputManifest(Timestamp time); private: - std::map m_input_manifest; - std::map m_output_manifest; - in_addr m_addr; - UINT64 m_id, - m_sid, - m_tid; - std::string m_name; + std::map m_input_manifest; + std::map m_output_manifest; + std::map m_chatlog; + + SOCKET m_sock; + sockaddr_in m_addr; + netprot::LoginInfo m_loginfo; + netprot::PlayerInfo m_playinfo; }; #endif \ No newline at end of file diff --git a/SQCSim-srv/define.h b/SQCSim-srv/define.h index 74c1c26..77ca08e 100644 --- a/SQCSim-srv/define.h +++ b/SQCSim-srv/define.h @@ -6,38 +6,12 @@ #include #include #include -#include #define MAX_CONNECTIONS 16 +#define ID_LIST_SIZE 127 +#define BUFFER_LENGTH 150 + typedef unsigned char LogDest; enum LOG_DEST { CONSOLE, LOGFILE, LOG_LAST }; -typedef std::chrono::system_clock::time_point Timestamp; - - -#ifdef _WIN32 - -#pragma comment(lib,"wsock32.lib") // Pour pouvoir faire fonctionner le linker sans le vcxproject - -#include -#include -#include - -#define popen _popen -#define pclose _pclose - -#else // Pas _WIN32 - -#include -#include -#include -#include -#include -#include - -#define SOCKET int -#define INVALID_SOCKET -1 -#define closesocket close - -#endif // _WIN32 #endif \ No newline at end of file diff --git a/SQCSim-srv/main.cpp b/SQCSim-srv/main.cpp index d67d836..a1e104d 100644 --- a/SQCSim-srv/main.cpp +++ b/SQCSim-srv/main.cpp @@ -1,4 +1,3 @@ -#include "define.h" #include "server.h" int main() { diff --git a/SQCSim-srv/server.cpp b/SQCSim-srv/server.cpp index e2740ba..17c5585 100644 --- a/SQCSim-srv/server.cpp +++ b/SQCSim-srv/server.cpp @@ -61,9 +61,6 @@ int Server::Init() { return 5; } - for (auto& conn : m_conn) - conn = nullptr; - return 0; } @@ -73,20 +70,73 @@ int Server::Ready() { return 1; } - char buffer[2048]; + char* buf = new char[150]; + uint32_t buflen = 150; bool readystart = false; + srand(time(NULL)); Log("À l'écoute sur le port: " + std::to_string(SRV_PORT), false, false); + buildIdList(ID_LIST_SIZE); + + m_game.countdown = 360; + m_game.gameType = 1; + m_game.seed = 9370707; + while (!readystart) { - - Log("trololo", false, false); - readystart = true; + sockaddr_in sockad; + int addrlen = sizeof(sockad); + SOCKET sock = accept(m_sock_tcp, (sockaddr*)&sockad, &addrlen); + + if (sock < 0) + Log("Erreur de connexion", true, false); + else if (sock > 0) { + std::string str = "Nouvelle connection provenant de: "; + char* strbuf = new char[BUFFER_LENGTH]; + uint32_t strbuflen = BUFFER_LENGTH; + + str.append(inet_ntop(AF_INET, &sockad.sin_addr, strbuf, strbuflen)).append(": ").append(std::to_string(sockad.sin_port)); + + if (recv(sock, buf, buflen, 0) > 0) { + netprot::LoginInfo log; + netprot::PlayerInfo play; + if (netprot::Deserialize(&log, buf, buflen)) { + log.sid = getUniqueId(); + + log.tid = 0; + + str.append(" Nom: ").append(log.name); + Log(str, false, false); + str = ""; + + str.append(log.name).append(" SID: [").append(std::to_string(log.sid).append("]")); + Log(str, false, false); + + //netprot::Serialize(&log, &buf, &buflen); + //send(sock, buf, buflen, 0); + //buflen = 150; + sendPack(sock, &log, &buf, &buflen); + + play.id = getUniqueId(); + memcpy(play.name, log.name, std::strlen(log.name) + 1); + play.tid = log.tid; + + //netprot::Serialize(&m_game, &buf, &buflen); + //send(sock, buf, buflen, 0); + sendPack(sock, &m_game, &buf, &buflen); + Connection* conn = new Connection(sock, sockad, log, play); + + m_players[log.sid] = conn; + readystart = true; + } + } + } } return 0; } void Server::Run() { + Log("Partie en cours...", false, false); } @@ -116,7 +166,7 @@ void Server::Log(std::string str, bool is_error = false, bool is_fatal = false) break; case LOG_DEST::CONSOLE: default: - std::cout << Timestamp() << (is_fatal? "FATAL ": "") << (is_error ? "ERROR ": "") << str << std::endl; + std::cout << Timestamp() << (is_fatal ? "FATAL " : "") << (is_error ? "ERROR " : "") << str << std::endl; break; } @@ -131,6 +181,41 @@ void Server::Log(std::string str, bool is_error = false, bool is_fatal = false) } } +void Server::buildIdList(size_t size) { + std::set lst; + + do lst.insert(((uint64_t)rand() << 25) % 8675309); // EIGHT SIX SEVENFIVE THREE AUGHT NIIIIIIiIIiiIiINE! + while (lst.size() < size); + + m_ids = std::vector(lst.begin(), lst.end()); +} + +uint64_t Server::getUniqueId() { + uint64_t id = m_ids.back(); + m_ids.pop_back(); + return id; +} + +// Test serialize/deserialize: +/* + netprot::LoginInfo log, log2; + std::cout << "Nom? "; + std::cin.getline(log.name, 32); // NO! STD::CIN >> VARIABLE;! EVEEEEEERRRR!!! + log.sid = 12345; + char* buf = new char[150]; + uint32_t buflen = 150; + + netprot::Serialize(&log, &buf, &buflen); + + bool is_work = netprot::Deserialize(&log2, buf, buflen); + + std::string str; + str.append(is_work ? "Y " : "N ").append(log2.name).append(": ").append(std::to_string(log2.sid)); + + Log(str, false, false); +*/ + + ///* Recevoir paquet */ //while (true) { // char buffer[2048]; diff --git a/SQCSim-srv/server.h b/SQCSim-srv/server.h index 2cb0618..425a996 100644 --- a/SQCSim-srv/server.h +++ b/SQCSim-srv/server.h @@ -3,8 +3,10 @@ #include #include +#include #include #include "../SQCSim-common/world.h" +#include "../SQCSim-common/netprotocol.h" #include "define.h" #include "connection.h" @@ -26,10 +28,27 @@ private: LogDest m_log; std::ofstream m_logfile; - Connection* m_conn[MAX_CONNECTIONS]; + std::map m_players; + std::map m_chatlog; + std::vector m_ids; + netprot::GameInfo m_game; + World* m_world = nullptr; std::string Timestamp(); void Log(std::string str, bool is_error, bool is_fatal); + void buildIdList(size_t size); + + uint64_t getUniqueId(); + template void sendPack(SOCKET sock, T* pack, char** buf, uint32_t* buflen); + }; + +template +void Server::sendPack(SOCKET sock, T* pack, char** buf, uint32_t* buflen) { + netprot::Serialize(pack, buf, buflen); + send(sock, *buf, *buflen, 0); + *buflen = BUFFER_LENGTH; +} + #endif diff --git a/SQCSim2021/SQCSim2021.vcxproj b/SQCSim2021/SQCSim2021.vcxproj index dfed398..9cac270 100644 --- a/SQCSim2021/SQCSim2021.vcxproj +++ b/SQCSim2021/SQCSim2021.vcxproj @@ -25,6 +25,7 @@ + @@ -37,7 +38,6 @@ - @@ -46,6 +46,7 @@ + @@ -60,6 +61,11 @@ + + + {ee91ab12-4225-4a4d-931d-69d72f6d91fb} + + {A21FD938-1FEA-4687-AB86-0EABAC30877B} Win32Proj diff --git a/SQCSim2021/SQCSim2021.vcxproj.filters b/SQCSim2021/SQCSim2021.vcxproj.filters index 4b2e6c9..60aa0a8 100644 --- a/SQCSim2021/SQCSim2021.vcxproj.filters +++ b/SQCSim2021/SQCSim2021.vcxproj.filters @@ -38,9 +38,6 @@ Fichiers d%27en-tête - - Fichiers d%27en-tête - Fichiers d%27en-tête @@ -74,6 +71,9 @@ Fichiers d%27en-tête + + Fichiers d%27en-tête + @@ -127,5 +127,8 @@ Fichiers sources + + Fichiers sources + \ No newline at end of file diff --git a/SQCSim2021/audio.h b/SQCSim2021/audio.h index 9e8e3be..315bfae 100644 --- a/SQCSim2021/audio.h +++ b/SQCSim2021/audio.h @@ -4,7 +4,7 @@ #include #include #include "define.h" -#include "vector3.h" +#include "../SQCSim-common/vector3.h" class Audio { private: diff --git a/SQCSim2021/chunk.cpp b/SQCSim2021/chunk.cpp index fe4c0a5..5d78859 100644 --- a/SQCSim2021/chunk.cpp +++ b/SQCSim2021/chunk.cpp @@ -1,13 +1,13 @@ #include "chunk.h" #include "world.h" -Chunk::Chunk(unsigned int x, unsigned int y) : m_posX(x), m_posY(y) { +Chunk::Chunk(unsigned int x, unsigned int y, int64_t seed) : m_posX(x), m_posY(y) { //std::ostringstream pos; // Vérifie l'existence d'un fichier .chunk avec sa position. //pos << CHUNK_PATH << x << '_' << y << ".chunk"; //std::ifstream input(pos.str(), std::fstream::binary); //if (input.fail()) { - OpenSimplexNoise::Noise simplex = OpenSimplexNoise::Noise(SEED); + OpenSimplexNoise::Noise simplex = OpenSimplexNoise::Noise(seed); m_blocks.Reset(BTYPE_AIR); for (int ix = 0; ix < CHUNK_SIZE_X; ++ix) // Montagnes diff --git a/SQCSim2021/chunk.h b/SQCSim2021/chunk.h index d4fdcb5..2ce15e8 100644 --- a/SQCSim2021/chunk.h +++ b/SQCSim2021/chunk.h @@ -25,7 +25,7 @@ class Chunk { void AddBlockToMesh(VertexBuffer::VertexData* vd, int& count, BlockType bt, int x, int y, int z, float u, float v, float s, World* world); public: - Chunk(unsigned int x, unsigned int y); + Chunk(unsigned int x, unsigned int y, int64_t seed); ~Chunk(); void RemoveBlock(int x, int y, int z, World* world); diff --git a/SQCSim2021/connector.cpp b/SQCSim2021/connector.cpp new file mode 100644 index 0000000..31e1b81 --- /dev/null +++ b/SQCSim2021/connector.cpp @@ -0,0 +1,101 @@ +#include "connector.h" + +Connector::Connector() {} + +Connector::~Connector() {} + +int Connector::Init() { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2, 2), &m_wsaData) != 0) { /* Initialisation de l'environnement reseau (Windows only) */ + std::cout << "Initialisation WinSock." << std::endl; + return 1; + } +#endif + + m_sock_udp = socket(AF_INET, SOCK_DGRAM, 0); + if (m_sock_udp == INVALID_SOCKET) { /* Creation du socket UDP */ + std::cout << "Creation Socket UDP." << std::endl; + return 2; + } + + m_sock_tcp = socket(AF_INET, SOCK_STREAM, 0); + if (m_sock_tcp == INVALID_SOCKET) { /* Creation du socket TCP */ + std::cout << "Creation Socket TCP." << std::endl; + return 3; + } + + /* Creation structure donnes descripteur du socket serveur */ + sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(CLI_PORT); + addr.sin_addr.s_addr = htonl(INADDR_ANY); + + if (bind(m_sock_udp, (sockaddr*)&addr, sizeof(addr)) != 0) { /* Associer le socket UDP au port */ + std::cout << "Association Socket UDP." << std::endl; + return 4; + } + + if (bind(m_sock_tcp, (sockaddr*)&addr, sizeof(addr)) != 0) { /* Associer le socket TCP au port */ + std::cout << "Association Socket TCP." << std::endl; + return 5; + } + return 0; +} + +int Connector::Connect(char* srv_addr, std::string name) { + sockaddr_in add; + m_srvsockaddr.sin_family = AF_INET; + m_srvsockaddr.sin_port = htons(SRV_PORT); + + if (inet_pton(AF_INET, srv_addr, &m_srvsockaddr.sin_addr) <= 0) { + std::cout << "Addresse serveur invalide." << std::endl; + return 1; + } + + if (connect(m_sock_tcp, (sockaddr*)&m_srvsockaddr, sizeof(m_srvsockaddr)) < 0) { + std::cout << "Échec de la connexion." << std::endl; + } + + char* buf = new char[150]; + uint32_t buflen = 150; + netprot::LoginInfo log; + memcpy(&log.name, name.c_str(), name.size() + 1); + + netprot::Serialize(&log, &buf, &buflen); + + int se = send(m_sock_tcp, buf, buflen, 0); + + delete[] buf; + buf = new char[150] {0}; + buflen = 150; + int rpack = 0; + + while (rpack < 2) { + recv(m_sock_tcp, buf, buflen, 0); + + switch (netprot::getType(buf, buflen)) { + case netprot::PACKET_TYPE::LOGINF: + if (!netprot::Deserialize(&m_loginfo, buf, buflen)) { + std::cout << "Packet LoginInfo invalide." << std::endl; + return 2; + } + ++rpack; + break; + case netprot::PACKET_TYPE::GAMEINFO: + if (!netprot::Deserialize(&m_gameinfo, buf, buflen)) { + std::cout << "Packet GameInfo invalide." << std::endl; + return 3; + } + ++rpack; + break; + default: + std::cout << "Packet invalide." << std::endl; + break; + } + } + return 0; +} + +uint64_t Connector::getId() const { return m_loginfo.sid; } + +unsigned int Connector::getSeed() const { return m_gameinfo.seed; } diff --git a/SQCSim2021/connector.h b/SQCSim2021/connector.h new file mode 100644 index 0000000..166c07b --- /dev/null +++ b/SQCSim2021/connector.h @@ -0,0 +1,36 @@ +#ifndef CONNECTOR_H__ +#define CONNECTOR_H__ + +#include "define.h" +#include "../SQCSim-common/netprotocol.h" +#include + +class Connector { +public: + Connector(); + ~Connector(); + + int Init(); + int Connect(char* srv_addr, std::string name); + uint64_t getId() const; + unsigned int getSeed() const; + + //void SendInput(); + //int Sync(); +private: +#ifdef _WIN32 + WSADATA m_wsaData; +#endif + std::map m_inputmanifest; + std::map m_players; + std::map m_teams; + + netprot::LoginInfo m_loginfo; + netprot::GameInfo m_gameinfo; + + sockaddr_in m_srvsockaddr; + SOCKET m_sock_udp = 0, + m_sock_tcp = 0; + +}; +#endif diff --git a/SQCSim2021/define.h b/SQCSim2021/define.h index 937d4b9..ceeb08c 100644 --- a/SQCSim2021/define.h +++ b/SQCSim2021/define.h @@ -1,28 +1,22 @@ -#ifndef DEFINE_H__ -#define DEFINE_H__ +#ifndef CLI_DEFINE_H__ +#define CLI_DEFINE_H__ +#include +#include +#include #include #include -#include -#include +#include "../SQCSim-common/define.h" #ifdef _WIN32 -#include #include #include #include #endif -#define CHUNK_SIZE_X 4 -#define CHUNK_SIZE_Y 64 -#define CHUNK_SIZE_Z 4 -#define MAX_SELECTION_DISTANCE 5 -#define BASE_WIDTH 640 -#define BASE_HEIGHT 480 -#define SEED 12345 - -#define WORLD_SIZE_X 64 -#define WORLD_SIZE_Y 64 +#define NETWORK_TEST false +#define SRV_ADDR "127.0.0.1" +#define COUNTDOWN 300 #define FRAMES_RENDER_CHUNKS 1 #define FRAMES_UPDATE_CHUNKS 1 @@ -32,13 +26,8 @@ #define THREADS_UPDATE_CHUNKS 3 #define THREADS_DELETE_CHUNKS 3 -#define VIEW_DISTANCE 512 -#define TEXTURE_SIZE 512 -#define MAX_BULLETS 512 - - -typedef uint8_t BlockType; -enum BLOCK_TYPE { BTYPE_AIR, BTYPE_DIRT, BTYPE_GRASS, BTYPE_METAL, BTYPE_ICE, BTYPE_LAST }; +#define BASE_WIDTH 640 +#define BASE_HEIGHT 480 #define TEXTURE_PATH "./media/textures/" #define SHADER_PATH "./media/shaders/" diff --git a/SQCSim2021/engine.cpp b/SQCSim2021/engine.cpp index a7ca3d4..a20a720 100644 --- a/SQCSim2021/engine.cpp +++ b/SQCSim2021/engine.cpp @@ -1,8 +1,4 @@ #include "engine.h" -#include -#include -#include "transformation.h" -#include "player.h" Engine::Engine() {} @@ -44,12 +40,29 @@ void Engine::Init() { m_skybox.Init(0.2f); // Objet de musique! - m_audio.ToggleMusicState(); + //m_audio.ToggleMusicState(); // Array pour les balles. for (int x = 0; x < MAX_BULLETS; ++x) m_bullets[x] = nullptr; + uint64_t seed = 0; + std::string playname = "La Chienne à Jacques"; + if (NETWORK_TEST) { // Test connexion réseau. + if (!m_conn.Init()) { + if (!m_conn.Connect(SRV_ADDR, playname)) { + // setup jeu en réseau. + std::cout << "ID reçu du serveur: " << std::to_string(m_conn.getId()) << "!" << std::endl; + std::cout << "Seed reçu du serveur: " << std::to_string(m_conn.getSeed()) << "!" << std::endl; + seed = m_conn.getSeed(); + } + else std::cout << "Erreur de connexion." << std::endl; + } + else std::cout << "Erreur de création de socket." << std::endl; + } + + m_world.SetSeed(seed); + // Init Chunks m_world.GetChunks().Reset(nullptr); @@ -192,7 +205,6 @@ void Engine::DisplayHud(int timer) { ss << "Time: " << (int)(timer / 60) << ":" << std::setw(2) << std::setfill('0') << timer % 60; PrintText(Width() - Width() * 0.15, Height() - (Height() / 19.2), scale, ss.str()); - } void Engine::DisplayInfo(float elapsedTime, BlockType bloc) { diff --git a/SQCSim2021/engine.h b/SQCSim2021/engine.h index 0d7156f..5ce52ec 100644 --- a/SQCSim2021/engine.h +++ b/SQCSim2021/engine.h @@ -1,6 +1,8 @@ #ifndef ENGINE_H__ #define ENGINE_H__ +#include +#include #include "define.h" #include "openglcontext.h" #include "texture.h" @@ -15,6 +17,7 @@ #include "array2d.h" #include "world.h" #include "bullet.h" +#include "connector.h" class Engine : public OpenglContext { public: @@ -46,6 +49,7 @@ private: void DrawHud(float elapsedTime, BlockType bloc); void PrintText(float x, float y, float scale, const std::string& t); + Connector m_conn; Shader m_shader01; BlockInfo* m_blockinfo[BTYPE_LAST]; TextureAtlas m_textureAtlas = TextureAtlas(BTYPE_LAST); diff --git a/SQCSim2021/matrix4.h b/SQCSim2021/matrix4.h index a0d911a..bf5ac5b 100644 --- a/SQCSim2021/matrix4.h +++ b/SQCSim2021/matrix4.h @@ -6,7 +6,7 @@ #include #include "define.h" -#include "vector3.h" +#include "../SQCSim-common/vector3.h" #ifndef M_PI #define M_PI 3.14159265f diff --git a/SQCSim2021/player.h b/SQCSim2021/player.h index 3466d1a..239b550 100644 --- a/SQCSim2021/player.h +++ b/SQCSim2021/player.h @@ -1,6 +1,6 @@ #ifndef _PLAYER_H__ #define _PLAYER_H__ -#include "vector3.h" +#include "../SQCSim-common/vector3.h" #include "transformation.h" #include "audio.h" #include diff --git a/SQCSim2021/transformation.h b/SQCSim2021/transformation.h index d147a58..764a781 100644 --- a/SQCSim2021/transformation.h +++ b/SQCSim2021/transformation.h @@ -2,7 +2,7 @@ #define TRANSFORMATION_H__ #include "matrix4.h" -#include "vector3.h" +#include "../SQCSim-common/vector3.h" #include class Transformation diff --git a/SQCSim2021/vector3.h b/SQCSim2021/vector3.h deleted file mode 100644 index b191681..0000000 --- a/SQCSim2021/vector3.h +++ /dev/null @@ -1,219 +0,0 @@ -#ifndef VECTOR3_H__ -#define VECTOR3_H__ - -#include -#include - -template -class Vector3 -{ -public: - Vector3(); - Vector3(const T& x, const T& y, const T& z); - ~Vector3(); - - T Length() const; - void Normalize(); - void Zero(); - - T Dot(const Vector3& v) const; - Vector3 Cross(const Vector3& v) const; - - Vector3 operator+(const Vector3& v) const; - Vector3 operator-(const Vector3& v) const; - Vector3 operator-() const; - Vector3 operator+(const T& v) const; - Vector3 operator-(const T& v) const; - Vector3 operator/(const T& v) const; - Vector3 operator*(const T& v) const; - - Vector3& operator=(const Vector3& v); - - Vector3& operator+=(const Vector3& v); - Vector3& operator-=(const Vector3& v); - Vector3& operator+=(const T& v); - Vector3& operator-=(const T& v); - Vector3& operator/=(const T& v); - Vector3& operator*=(const T& v); - - bool operator==(const Vector3& v) const; - bool operator!=(const Vector3& v) const; - - void Afficher() const; - -public: - T x, y, z; -}; - -typedef Vector3 Vector3i; -typedef Vector3 Vector3f; - -template -inline std::ostream& operator<<(std::ostream& out, const Vector3& v) -{ - out << "[" << v.x << ", " << v.y << ", " << v.z << "]"; - return out; -} - - -template -Vector3::Vector3() -{ -} - -template -Vector3::Vector3(const T& x, const T& y, const T& z) : x(x), y(y), z(z) -{ -} - -template -Vector3::~Vector3() -{ -} - -template -T Vector3::Length() const -{ - return sqrt(x*x + y*y + z*z); -} - -template -void Vector3::Normalize() -{ - T len = Length(); - if (len != 0) - { - x /= len; - y /= len; - z /= len; - } -} - -template -void Vector3::Zero() -{ - x = y = z = 0; -} - -template -T Vector3::Dot(const Vector3& v) const -{ - return (x * v.x) + (y * v.y) + (z * v.z); -} - -template -Vector3 Vector3::Cross(const Vector3& v) const -{ - return Vector3( - y * v.z - v.y * z, - z * v.x - v.z * x, - x * v.y - v.x * y); -} - -template -Vector3 Vector3::operator+(const Vector3& v) const -{ - return Vector3(x + v.x, y + v.y, z + v.z); -} - -template -Vector3 Vector3::operator-(const Vector3& v) const -{ - return Vector3(x - v.x, y - v.y, z - v.z); -} - -template -Vector3 Vector3::operator-() const -{ - return Vector3(-x, -y, -z); -} - -template -Vector3 Vector3::operator+(const T& v) const -{ - return Vector3(x + v, y + v, z + v); -} - -template -Vector3 Vector3::operator-(const T& v) const -{ - return Vector3(x - v, y - v, z - v); -} - -template -Vector3 Vector3::operator/(const T& v) const -{ - return Vector3(x / v, y / v, z / v); -} - -template -Vector3 Vector3::operator*(const T& v) const -{ - return Vector3(x * v, y * v, z * v); -} - -template -Vector3& Vector3::operator=(const Vector3& v) -{ - x = v.x; - y = v.y; - z = v.z; - return *this; -} - -template -Vector3& Vector3::operator+=(const Vector3& v) -{ - return (*this = *this + v); -} - -template -Vector3& Vector3::operator-=(const Vector3& v) -{ - return (*this = *this - v); -} - -template -Vector3& Vector3::operator+=(const T& v) -{ - return (*this = *this + v); -} - -template -Vector3& Vector3::operator-=(const T& v) -{ - return (*this = *this - v); -} - -template -Vector3& Vector3::operator/=(const T& v) -{ - return (*this = *this / v); -} - -template -Vector3& Vector3::operator*=(const T& v) -{ - return (*this = *this * v); -} - -template -bool Vector3::operator==(const Vector3& v) const -{ - return (x == v.x && y == v.y && z == v.z); -} - -template -bool Vector3::operator!=(const Vector3& v) const -{ - return !(*this == v); -} - -template -void Vector3::Afficher() const -{ - std::cout << "[" << x << ", " << y << ", " << z << "]" << std::endl; -} - - -#endif // VECTOR3_H__ diff --git a/SQCSim2021/world.cpp b/SQCSim2021/world.cpp index bbd86c0..dc5e5b6 100644 --- a/SQCSim2021/world.cpp +++ b/SQCSim2021/world.cpp @@ -6,6 +6,10 @@ World::~World() {} Array2d& World::GetChunks() { return m_chunks; } +void World::SetSeed(uint64_t seed) { + m_seed = seed; +} + Chunk* World::ChunkAt(float x, float y, float z) const { int cx = (int)x / CHUNK_SIZE_X; int cz = (int)z / CHUNK_SIZE_Z; @@ -330,7 +334,12 @@ void World::UpdateWorld(Player& player, BlockInfo* blockinfo[BTYPE_LAST]) { chy = cy + ty * CHUNK_SIZE_Z; if (chx < WORLD_SIZE_X * CHUNK_SIZE_X && chy < WORLD_SIZE_Y * CHUNK_SIZE_Z && chx >= 0 && chy >= 0 && !ChunkAt(chx, 1, chy)) - genThList[threads++] = std::async(std::launch::async, [](unsigned int x, unsigned int y) { return new Chunk(x, y); }, chx / CHUNK_SIZE_X + m_center[0], chy / CHUNK_SIZE_Z + m_center[1]); + genThList[threads++] = std::async(std::launch::async, + [](unsigned int x, unsigned int y, uint64_t seed) { + return new Chunk(x, y, seed); }, + chx / CHUNK_SIZE_X + m_center[0], + chy / CHUNK_SIZE_Z + m_center[1], + m_seed); if (threads == THREADS_GENERATE_CHUNKS) frameGenerate = FRAMES_RENDER_CHUNKS; } for (; ty <= side; ++ty) { @@ -340,7 +349,12 @@ void World::UpdateWorld(Player& player, BlockInfo* blockinfo[BTYPE_LAST]) { chy = cy + ty * CHUNK_SIZE_Z; if (chx < WORLD_SIZE_X * CHUNK_SIZE_X && chy < WORLD_SIZE_Y * CHUNK_SIZE_Z && chx >= 0 && chy >= 0 && !ChunkAt(chx, 1, chy)) - genThList[threads++] = std::async(std::launch::async, [](unsigned int x, unsigned int y) { return new Chunk(x, y); }, chx / CHUNK_SIZE_X + m_center[0], chy / CHUNK_SIZE_Z + m_center[1]); + genThList[threads++] = std::async(std::launch::async, + [](unsigned int x, unsigned int y, uint64_t seed) { + return new Chunk(x, y, seed); }, + chx / CHUNK_SIZE_X + m_center[0], + chy / CHUNK_SIZE_Z + m_center[1], + m_seed); if (threads == THREADS_GENERATE_CHUNKS) frameGenerate = FRAMES_RENDER_CHUNKS; } for (; tx >= -side; --tx) { @@ -350,7 +364,12 @@ void World::UpdateWorld(Player& player, BlockInfo* blockinfo[BTYPE_LAST]) { chy = cy + ty * CHUNK_SIZE_Z; if (chx < WORLD_SIZE_X * CHUNK_SIZE_X && chy < WORLD_SIZE_Y * CHUNK_SIZE_Z && chx >= 0 && chy >= 0 && !ChunkAt(chx, 1, chy)) - genThList[threads++] = std::async(std::launch::async, [](unsigned int x, unsigned int y) { return new Chunk(x, y); }, chx / CHUNK_SIZE_X + m_center[0], chy / CHUNK_SIZE_Z + m_center[1]); + genThList[threads++] = std::async(std::launch::async, + [](unsigned int x, unsigned int y, uint64_t seed) { + return new Chunk(x, y, seed); }, + chx / CHUNK_SIZE_X + m_center[0], + chy / CHUNK_SIZE_Z + m_center[1], + m_seed); if (threads == THREADS_GENERATE_CHUNKS) frameGenerate = FRAMES_RENDER_CHUNKS; } for (; ty >= -side; --ty) { @@ -360,7 +379,12 @@ void World::UpdateWorld(Player& player, BlockInfo* blockinfo[BTYPE_LAST]) { chy = cy + ty * CHUNK_SIZE_Z; if (chx < WORLD_SIZE_X * CHUNK_SIZE_X && chy < WORLD_SIZE_Y * CHUNK_SIZE_Z && chx >= 0 && chy >= 0 && !ChunkAt(chx, 1, chy)) - genThList[threads++] = std::async(std::launch::async, [](unsigned int x, unsigned int y) { return new Chunk(x, y); }, chx / CHUNK_SIZE_X + m_center[0], chy / CHUNK_SIZE_Z + m_center[1]); + genThList[threads++] = std::async(std::launch::async, + [](unsigned int x, unsigned int y, uint64_t seed) { + return new Chunk(x, y, seed); }, + chx / CHUNK_SIZE_X + m_center[0], + chy / CHUNK_SIZE_Z + m_center[1], + m_seed); if (threads == THREADS_GENERATE_CHUNKS) frameGenerate = FRAMES_RENDER_CHUNKS; } if (frameGenerate) diff --git a/SQCSim2021/world.h b/SQCSim2021/world.h index d4b1545..486e2d2 100644 --- a/SQCSim2021/world.h +++ b/SQCSim2021/world.h @@ -8,7 +8,7 @@ #include "define.h" #include "chunk.h" #include "array2d.h" -#include "vector3.h" +#include "../SQCSim-common/vector3.h" #include "player.h" #include "transformation.h" #include "shader.h" @@ -26,6 +26,8 @@ public: Array2d& GetChunks(); + void SetSeed(uint64_t seed); + Chunk* ChunkAt(float x, float y, float z) const; Chunk* ChunkAt(const Vector3f& pos) const; @@ -43,6 +45,7 @@ public: private: Array2d m_chunks = Array2d(WORLD_SIZE_X, WORLD_SIZE_Y); std::vector m_tbDeleted; + uint64_t m_seed = 0; unsigned int m_center[2] = { UINT16_MAX / 2 - WORLD_SIZE_X, UINT16_MAX / 2 - WORLD_SIZE_Y };