diff --git a/CMakeLists.txt b/CMakeLists.txt index e41a1330..ba726d69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,12 @@ add_executable(zeus zeus/client/SceneManager.cpp zeus/client/SceneManager.h zeus/client/Scene.h - zeus/client/ClientState.h) + zeus/client/ClientState.h + zeus/game/MenuScene.cpp + zeus/game/MenuScene.h + zeus/server/Server.cpp + zeus/server/Server.h + zeus/client/ClientPacket.cpp + zeus/client/ClientPacket.h zeus/server/ClientConnection.cpp zeus/server/ClientConnection.h zeus/server/Packet.cpp zeus/server/Packet.h) target_link_libraries(zeus ${OPENGL_gl_LIBRARY} glfw libGLEW.so pthread lua dl) diff --git a/lua/file.lua b/lua/file.lua index 61417463..de396d04 100644 --- a/lua/file.lua +++ b/lua/file.lua @@ -151,7 +151,7 @@ zeus.register_blockmodel("default:plantlike", { zeus.register_blockmodel("default:block_poof", { { face = "left", - tex = 0, + tex = 1, points = { 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, @@ -160,7 +160,7 @@ zeus.register_blockmodel("default:block_poof", { } }, { face = "right", - tex = 0, + tex = 1, points = { 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, @@ -169,7 +169,7 @@ zeus.register_blockmodel("default:block_poof", { } }, { face = "top", - tex = 0, + tex = 1, points = { 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, @@ -178,7 +178,7 @@ zeus.register_blockmodel("default:block_poof", { } }, { face = "bottom", - tex = 0, + tex = 1, points = { 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, @@ -187,7 +187,7 @@ zeus.register_blockmodel("default:block_poof", { } }, { face = "front", - tex = 0, + tex = 1, points = { 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, @@ -196,7 +196,7 @@ zeus.register_blockmodel("default:block_poof", { } }, { face = "back", - tex = 0, + tex = 1, points = { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, @@ -205,16 +205,16 @@ zeus.register_blockmodel("default:block_poof", { } }, { face = "nocull", - tex = 0, + tex = 2, points = { -0.31, 1.30, -0.3, 0, 0, -0.31, -0.30, -0.31, 0, 1, 1.3, -0.30, 1.3, 1, 1, 1.3, 1.30, 1.29, 1, 0, - -0.31, 1.30, -0.3, 0, 0, - -0.31, -0.30, -0.31, 0, 1, 1.3, -0.30, 1.3, 1, 1, + -0.31, -0.30, -0.31, 0, 1, + -0.31, 1.30, -0.3, 0, 0, 1.3, 1.30, 1.29, 1, 0, -0.31, 1.30, 1.29, 0, 0, @@ -222,9 +222,9 @@ zeus.register_blockmodel("default:block_poof", { 1.3, -0.30, -0.31, 1, 1, 1.3, 1.30, -0.3, 1, 0, - -0.31, 1.30, 1.29, 0, 0, - -0.31, -0.30, 1.3, 0, 1, 1.3, -0.30, -0.31, 1, 1, + -0.31, -0.30, 1.3, 0, 1, + -0.31, 1.30, 1.29, 0, 0, 1.3, 1.30, -0.3, 1, 0 } } @@ -379,3 +379,25 @@ zeus.register_block('default:stone', { model = "default:block", textures = {"default_stone_dark"} }) + +-- Leaves +zeus.register_block('default:leaves', { + name = "Log", + model = "default:block_poof", + textures = { + "default_leaves", + "default_leaves_puff" + } +}) + + +-- Wood +zeus.register_block('default:wood', { + name = "Log", + model = "default:block", + textures = { + "default_log_top", + "default_log_top", + "default_log_side" + } +}) diff --git a/tex/game/default_leaves_puff.png b/tex/game/default_leaves_puff.png index c6c03411..4bd22265 100644 Binary files a/tex/game/default_leaves_puff.png and b/tex/game/default_leaves_puff.png differ diff --git a/textureAtlas.png b/textureAtlas.png index 93e78e36..31598c75 100644 Binary files a/textureAtlas.png and b/textureAtlas.png differ diff --git a/zeus/Main.cpp b/zeus/Main.cpp index 628fa59f..cf2fa699 100644 --- a/zeus/Main.cpp +++ b/zeus/Main.cpp @@ -5,70 +5,26 @@ #include "client/Client.h" -//std::string make_daytime_string() { -// std::time_t now = std::time(nullptr); -// return "HIfhjdsfjhglfgkhkdfjhbhnjgdsk,jfgbhdksijfghgjfkwaslodfjgbhfdsklofjghnbgkmdsk,lfkgbna"; -//// return std::ctime(&now); -//} - -//void server() { -// try { -// asio::io_context io_context; -// udp::socket socket(io_context, udp::endpoint(udp::v4(), 12345)); -// -// for (;;) { -// char recv_buf[128]; -// udp::endpoint remote_endpoint; //Populated by the next line -// -// Timer t("owo"); -// socket.receive_from(asio::buffer(recv_buf), remote_endpoint); -// t.printElapsedSeconds(); -// std::cout << recv_buf << std::endl; -// -// std::string message = make_daytime_string(); -// -// asio::error_code ignored_error; -// socket.send_to(asio::buffer(message), remote_endpoint, 0, ignored_error); -// -// //Socket is garbage collected here, so like, don't do that? -// } -// } -// catch (std::exception& e) { -// std::cerr << e.what() << std::endl; -// } -//} - int main(int argc, char* argv[]) { -// auto serverThread = new std::thread(server); -// this_thread::sleep_for(0.2s); -// -// try { -// asio::io_context io_context; -// udp::resolver resolver(io_context); -// udp::endpoint receiver_endpoint = *resolver.resolve(udp::v4(), "127.0.0.1", "12345").begin(); -// -// udp::socket socket(io_context); -// socket.open(udp::v4()); -// -// char send_buf[3] = {'a', 'b', 'c'}; -// socket.send_to(asio::buffer(send_buf), receiver_endpoint); -// -// char recv_buf[20]; -// -// udp::endpoint sender_endpoint; //Populated by the next line -// size_t len = socket.receive_from(asio::buffer(recv_buf), sender_endpoint); -// -// sender_endpoint. -// -// std::cout.write(recv_buf, len); -//// std::cout << "Done " << len << std::endl; -// } -// catch (std::exception& e) { -// std::cout << e.what() << std::endl; -// } + std::string start = "client"; + if (argc >= 2) { + start = argv[1]; + } + if (start == "client") { + Client c(1366, 768); + c.start(nullptr); + } + + else if (start == "local") { + Client c(1366, 768); + c.start(argv[0]); //TODO: Get this to client some other way + } + + else if (start == "server") { + Server s(12345); + s.start(); + } - Client c(1366, 768); - c.start(); return 0; } \ No newline at end of file diff --git a/zeus/client/Client.cpp b/zeus/client/Client.cpp index 04d33548..7b09c457 100644 --- a/zeus/client/Client.cpp +++ b/zeus/client/Client.cpp @@ -2,8 +2,13 @@ // Created by aurailus on 06/01/19. // +#include +#include #include "Client.h" -#include "../game/GameScene.h" +#include "../server/Packet.h" +#include + +using asio::ip::udp; Client::Client() = default; @@ -11,15 +16,87 @@ Client::Client(int width, int height) { renderer = new Renderer(width, height); } -void Client::start() { +void Client::start(char* path) { +// Start Local Server + if (path != nullptr) { + int pid = fork(); + if (pid == 0) { + char *arr[] = { + (char *) "xterm", + (char *) "-iconic", + (char *) "-e", + path, + (char *) "server", + (char *) nullptr}; + + execvp("xterm", arr); + } else { + local_server_pid = pid; + } + } + + //Create ClientState struct state = new ClientState { .renderer = renderer, .fps = 0, .deltaTime = 0 }; - Scene* s = new GameScene(state); - sceneManager.setScene(s); //Main Menu Scene here eventually + //Start the Main Menu + Scene* m = new MenuScene(state); + sceneManager.setScene(m); + + //Try to connect to a server + try { + asio::io_context io_context; + udp::resolver resolver(io_context); + udp::endpoint receiver_endpoint = *resolver.resolve(udp::v4(), "127.0.0.1", "12346").begin(); + + udp::socket socket(io_context); + socket.open(udp::v4()); + + int attempts = 0; + bool connected = false; + while (!connected) { + if (attempts > 5) { + break; + } + + Packet p(Packet::HANDSHAKE); + p.addInt(attempts); + auto send_buf = p.serialize(); + + socket.send_to(asio::buffer(send_buf, send_buf.size()), receiver_endpoint); + attempts++; + + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + + if (socket.available() > 0) { + std::cout << "Connected" << std::endl; + connected = true; + } + else { + std::cout << "Failed to connect..." << std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds((attempts < 3 ? 50 : 700))); + } + } + if (!connected) { + std::cout << "Connection timed out!" << std::endl; + return; + } + + char recv_buf[20]; + + udp::endpoint sender_endpoint; //Populated by the next line + size_t len = socket.receive_from(asio::buffer(recv_buf), sender_endpoint); + + std::cout.write(recv_buf, len); + std::cout << "Done " << len << std::endl; + } + catch (std::exception &e) { + std::cout << e.what() << std::endl; + } + while (!renderer->getWindow()->getShouldClose()) loop(); } @@ -31,6 +108,12 @@ void Client::loop() { state->deltaTime = now - timeElapsed; timeElapsed = now; + count ++; + if (count == 20) { + Scene* g = new GameScene(state); + sceneManager.setScene(g); //Main Menu Scene here eventually + } + glfwPollEvents(); sceneManager.update(); @@ -40,6 +123,9 @@ void Client::loop() { } void Client::cleanup() { + if (local_server_pid != 0) { + kill(local_server_pid, SIGKILL); + } sceneManager.cleanupScene(); delete state; delete renderer; diff --git a/zeus/client/Client.h b/zeus/client/Client.h index 582decf7..d25a2978 100644 --- a/zeus/client/Client.h +++ b/zeus/client/Client.h @@ -9,13 +9,15 @@ #include "../engine/Timer.h" #include "SceneManager.h" #include "ClientState.h" +#include "../game/GameScene.h" +#include "../game/MenuScene.h" class Client { public: Client(); Client(int width, int height); - void start(); + void start(char* path); ~Client(); @@ -29,6 +31,9 @@ private: ClientState* state; SceneManager sceneManager; + int local_server_pid = 0; + int count = 0; + double timeElapsed = 0.0f; }; diff --git a/zeus/client/Scene.h b/zeus/client/Scene.h index 0db56950..e5111df8 100644 --- a/zeus/client/Scene.h +++ b/zeus/client/Scene.h @@ -13,11 +13,17 @@ public: this->state = state; }; - virtual void update() {}; + virtual void update() { + std::cerr << "State doesn't define update method!" << std::endl; + }; - virtual void draw() {}; + virtual void draw() { + std::cerr << "State doesn't define draw method!" << std::endl; + }; - virtual void cleanup() {}; + virtual void cleanup() { + std::cerr << "State doesn't define cleanup method!" << std::endl; + }; ClientState* state; }; diff --git a/zeus/client/SceneManager.cpp b/zeus/client/SceneManager.cpp index d6b78d65..8151698f 100644 --- a/zeus/client/SceneManager.cpp +++ b/zeus/client/SceneManager.cpp @@ -4,7 +4,9 @@ #include "SceneManager.h" -SceneManager::SceneManager() = default; +SceneManager::SceneManager() { + scene = nullptr; +}; void SceneManager::update() { scene->update(); diff --git a/zeus/engine/Window.cpp b/zeus/engine/Window.cpp index 55f9f867..1feed233 100644 --- a/zeus/engine/Window.cpp +++ b/zeus/engine/Window.cpp @@ -44,10 +44,10 @@ int Window::initialize() { // glEnable(GL_MULTISAMPLE); //VSync 1 = On, 0 = Off - glfwSwapInterval(1); + glfwSwapInterval(0); //Create the window - mainWindow = glfwCreateWindow(width, height, "Zeus_cpp OPENGL Linux x64", nullptr, nullptr); + mainWindow = glfwCreateWindow(width, height, "Zeus Alpha", nullptr, nullptr); if (!mainWindow) { printf("GLFW window failed"); diff --git a/zeus/game/GameScene.cpp b/zeus/game/GameScene.cpp index d342c258..11bed283 100644 --- a/zeus/game/GameScene.cpp +++ b/zeus/game/GameScene.cpp @@ -7,7 +7,6 @@ #include "../lua_api/l_register_blockmodel.h" GameScene::GameScene(ClientState* state) : Scene(state) { - textureAtlas = new TextureAtlas("../tex"); blockAtlas = new BlockAtlas(textureAtlas); @@ -40,7 +39,6 @@ GameScene::GameScene(ClientState* state) : Scene(state) { gui.pushGuiObjects(guiEntities); - auto crosshairTexture = new Texture((char*)"../tex/gui/crosshair.png"); crosshairTexture->load(); auto crosshair = new Entity(); @@ -74,58 +72,25 @@ GameScene::GameScene(ClientState* state) : Scene(state) { void GameScene::update() { - - auto camera = state->renderer->getCamera(); auto window = state->renderer->getWindow(); - player->update(window->getKeysArray(), (GLfloat)state->deltaTime, window->getDeltaX(), window->getDeltaY()); - - glm::vec3 round = World::roundVec(*camera->getPosition()); - round.y -= 2; - - int block = world->getBlock(round); - std::string on = "Null"; - if (block >= 0) { - on = blockAtlas->getBlock(block)->getIdentifier(); - } - - block = 0; - for (Ray ray(player); ray.getLength() < 5; ray.step(0.01)) { - auto found = world->getBlock(*ray.getEnd()); - if (found > 0) { - block = found; - if (state->renderer->getWindow()->mouseIsDown()) { - world->setBlock(*ray.getEnd(), 0); - } - break; - } - } - - std::string look = "Null"; - if (block >= 0) { - look = blockAtlas->getBlock(block)->getIdentifier(); - } - - gui.update(player->getPos(), player->getVel(), player->getYaw(), player->getPitch(), on, look, state->fps); + player->update(window->getKeysArray(), state->deltaTime, window->getDeltaX(), window->getDeltaY()); + gui.update(player, world, window, blockAtlas, state->fps); world->update(); } void GameScene::draw() { - Timer t("Drawing"); - state->renderer->begin(); - state->renderer->enableWorldShader(); + textureAtlas->getTexture()->use(); - for (auto &chunk : *world->getMeshChunks()) { + for (auto &chunk : *world->getMeshChunks()) state->renderer->draw(chunk.second); - } - for (auto &entity : entities) { + for (auto &entity : entities) state->renderer->draw(entity); - } state->renderer->enableGuiShader(); @@ -136,9 +101,12 @@ void GameScene::draw() { prevTexture = gui->getTexture(); gui->getTexture()->use(); } - state->renderer->drawGui(gui); } state->renderer->end(); +} + +void GameScene::cleanup() { + //TODO: Clean up } \ No newline at end of file diff --git a/zeus/game/GameScene.h b/zeus/game/GameScene.h index 948de147..4676366f 100644 --- a/zeus/game/GameScene.h +++ b/zeus/game/GameScene.h @@ -18,14 +18,17 @@ #include "world/Player.h" #include "../engine/Ray.h" #include "../client/Scene.h" +#include "../server/Server.h" class GameScene : public Scene { public: - GameScene(ClientState* state); + explicit GameScene(ClientState* state); void update() override; void draw() override; + + void cleanup() override; public: Player* player; diff --git a/zeus/game/MenuScene.cpp b/zeus/game/MenuScene.cpp new file mode 100644 index 00000000..0c860f40 --- /dev/null +++ b/zeus/game/MenuScene.cpp @@ -0,0 +1,57 @@ +// +// Created by aurailus on 08/01/19. +// + +#include "MenuScene.h" +#include "../engine/graphics/HudText.h" + +MenuScene::MenuScene(ClientState *state) : Scene(state) { + fontTexture = new Texture((char*)"../tex/gui/font.png"); + fontTexture->load(); + + auto alphaText = new HudText(fontTexture); + alphaText->set("Zeus Alpha 0.01"); + alphaText->setScale(3); + alphaText->setPosition(glm::vec3(8, 4, 0)); + entities.push_back(alphaText); + + auto titleText = new HudText(fontTexture); + titleText->set("Zeus"); + titleText->setScale(12); + titleText->setPosition(glm::vec3(490, 120, 0)); + entities.push_back(titleText); + + auto mainMenuText = new HudText(fontTexture); + mainMenuText->set("MAIN MENU"); + mainMenuText->setScale(4); + mainMenuText->setPosition(glm::vec3(530, 230, 0)); + entities.push_back(mainMenuText); +} + +void MenuScene::update() { + //Nothing +} + +void MenuScene::draw() { + state->renderer->begin(); + + state->renderer->enableGuiShader(); + + Texture* prevTexture = nullptr; + + for (auto &element : entities) { + if (element->getTexture() != prevTexture) { + prevTexture = element->getTexture(); + prevTexture->use(); + } + + state->renderer->drawGui(element); + } + + state->renderer->end(); +} + +void MenuScene::cleanup() { + fontTexture->clear(); + delete fontTexture; +} \ No newline at end of file diff --git a/zeus/game/MenuScene.h b/zeus/game/MenuScene.h new file mode 100644 index 00000000..218da33d --- /dev/null +++ b/zeus/game/MenuScene.h @@ -0,0 +1,29 @@ +// +// Created by aurailus on 08/01/19. +// + +#ifndef ZEUS_MENUSCENE_H +#define ZEUS_MENUSCENE_H + + +#include "../client/ClientState.h" +#include "../client/Scene.h" + +class MenuScene : public Scene { +public: + explicit MenuScene(ClientState* state); + + void update() override; + + void draw() override; + + void cleanup() override; + +private: + Texture* fontTexture; + std::vector entities; +// DebugGui gui; +}; + + +#endif //ZEUS_MENUSCENE_H diff --git a/zeus/game/gui/DebugGui.cpp b/zeus/game/gui/DebugGui.cpp index 5819979e..94606de6 100644 --- a/zeus/game/gui/DebugGui.cpp +++ b/zeus/game/gui/DebugGui.cpp @@ -24,10 +24,6 @@ DebugGui::DebugGui() { playerText->setScale(2); playerText->setPosition(glm::vec3(8, 42, 0)); - blockText = new HudText(fontTexture); - blockText->setScale(2); - blockText->setPosition(glm::vec3(8, 116, 0)); - fpsHistogram = new Entity(); fpsHistogram->create(new Mesh(), histogramTexture); fpsHistogram->setPosition(glm::vec3(8, 764, 0)); @@ -36,7 +32,6 @@ DebugGui::DebugGui() { void DebugGui::pushGuiObjects(std::vector &list) { list.push_back(alphaText); list.push_back(fpsText); - list.push_back(blockText); list.push_back(playerText); list.push_back(fpsHistogram); } @@ -94,9 +89,35 @@ std::string string_double(double val) { return string_float((float)val); } -void DebugGui::update(glm::vec3* pos, glm::vec3* vel, float yaw, float pitch, std::string block, std::string look, double fps) { - glm::vec3 chk = World::chunkVec(*pos); - glm::vec3 loc = World::localVec(*pos); +void DebugGui::update(Player* player, World* world, Window* window, BlockAtlas* atlas, double fps) { + glm::vec3 round = World::roundVec(*player->getPos()); + round.y -= 2; + + int block = world->getBlock(round); + std::string on = "ignore"; + if (block >= 0) { + on = atlas->getBlock(block)->getIdentifier(); + } + + block = 0; + for (Ray ray(player); ray.getLength() < 5; ray.step(0.01)) { + auto found = world->getBlock(*ray.getEnd()); + if (found > 0) { + block = found; + if (window->mouseIsDown()) { + world->setBlock(*ray.getEnd(), 0); + } + break; + } + } + + std::string look = "ignore"; + if (block >= 0) { + look = atlas->getBlock(block)->getIdentifier(); + } + + glm::vec3 chk = World::chunkVec(*player->getPos()); + glm::vec3 loc = World::localVec(*player->getPos()); if (fpsHistory.size() > FPS_HISTOGRAM_SIZE) fpsHistory.erase(fpsHistory.begin()); @@ -105,13 +126,13 @@ void DebugGui::update(glm::vec3* pos, glm::vec3* vel, float yaw, float pitch, st fpsHistUpdate(); playerText->set( - "W: " + to_string((int)pos->x) + "," + to_string((int)pos->y) + "," + to_string((int)pos->z) + "\n" + + "Chunk: " + to_string(world->lastGenUpdates) + ",Mesh: " + to_string(world->lastMeshUpdates) + "\n" + + "W: " + to_string((int)player->getPos()->x) + "," + to_string((int)player->getPos()->y) + "," + to_string((int)player->getPos()->z) + "\n" + "C: " + to_string((int)chk.x) + "," + to_string((int)chk.y) + "," + to_string((int)chk.z) + " " + "(" + to_string((int)loc.x) + "," + to_string((int)loc.y) + "," + to_string((int)loc.z) + ")\n" + - "V: " + string_float(vel->x) + "," + string_float(vel->y) + "," + string_float(vel->z) + "\n" + - "Yaw: " + string_float(yaw) + ", Pitch: " + string_float(pitch)); - - blockText->set("On: " + block + "\nLooking: " + look); + "V: " + string_float(player->getVel()->x) + "," + string_float(player->getVel()->y) + "," + string_float(player->getVel()->z) + "\n" + + "Yaw: " + string_float(player->getYaw()) + ", Pitch: " + string_float(player->getPitch()) + "\n" + + "On: " + on + "\nLooking: " + look); } DebugGui::~DebugGui() = default; \ No newline at end of file diff --git a/zeus/game/gui/DebugGui.h b/zeus/game/gui/DebugGui.h index 998e2c88..1195a208 100644 --- a/zeus/game/gui/DebugGui.h +++ b/zeus/game/gui/DebugGui.h @@ -5,9 +5,11 @@ #ifndef ZEUS_DEBUGGUI_H #define ZEUS_DEBUGGUI_H - #include "../../engine/graphics/HudText.h" #include "../world/World.h" +#include "../world/Player.h" +#include "../../engine/Window.h" +#include "../../engine/Ray.h" #include class DebugGui { @@ -15,7 +17,7 @@ public: DebugGui(); void pushGuiObjects(std::vector &list); - void update(glm::vec3* pos, glm::vec3* vel, float yaw, float pitch, std::string block, std::string look, double fps); + void update(Player* player, World* world, Window* window, BlockAtlas* atlas, double fps); ~DebugGui(); @@ -28,7 +30,6 @@ private: HudText* fpsText; HudText* alphaText; HudText* playerText; - HudText* blockText; Entity* fpsHistogram; const int FPS_HISTOGRAM_SIZE = 120; diff --git a/zeus/game/world/Player.cpp b/zeus/game/world/Player.cpp index db2f4075..ffa84971 100644 --- a/zeus/game/world/Player.cpp +++ b/zeus/game/world/Player.cpp @@ -29,7 +29,7 @@ void Player::posUpdate(bool *keys, double delta) { float jumpVel = 0.14f; float friction = 0.3f; - auto moveMult = (float)(moveSpeed * delta); + double moveMult = moveSpeed * delta; if (keys[GLFW_KEY_LEFT_SHIFT]) { moveMult *= 2; } @@ -45,7 +45,7 @@ void Player::posUpdate(bool *keys, double delta) { if (keys[GLFW_KEY_A]) mod -= rightFlat; if (glm::length(mod) != 0) mod = glm::normalize(mod); - mod = mod * moveMult; + mod = mod * (float)moveMult; glm::vec3 velFlat = glm::vec3(vel.x, 0, vel.z); velFlat = velFlat * (1.0f-friction) + mod * friction; diff --git a/zeus/game/world/World.cpp b/zeus/game/world/World.cpp index c365c4e5..3e1e7dcf 100644 --- a/zeus/game/world/World.cpp +++ b/zeus/game/world/World.cpp @@ -108,6 +108,7 @@ void World::handleChunkGenQueue() { } Timer t("Chunk Initialization"); + int genUpdates = 0; for (auto iter = finishedGen.begin(); iter != finishedGen.end(); ) { if (t.elapsedNs() > 4000000) break; @@ -116,7 +117,10 @@ void World::handleChunkGenQueue() { commitChunk(threadData->pos, threadData->chunk); iter = finishedGen.erase(iter); delete threadData; + + genUpdates++; } + lastGenUpdates = genUpdates; // t.printElapsedMs(); } @@ -124,8 +128,8 @@ void World::handleChunkGenQueue() { //Takes a threadDef object which contains a vector of tasks to do, and infinitely loops, completing tasks and //re-inserting them into the vector to be further manipulated by the main thread. void World::chunkGenThread(World::ChunkThreadDef* threadDef) { - PerlinNoise p(10); - PerlinNoise p2(10); + PerlinNoise p(9); + PerlinNoise p2(9); //Infinite loop while (true) { @@ -167,6 +171,15 @@ void World::chunkGenThread(World::ChunkThreadDef* threadDef) { int block = (val > 0) ? (val > 1) ? (val > 3) ? 3 : 2 : 1 : 0; blocks->push_back(block); } +// +// (*blocks)[ArrayTrans3D::vecToInd(8, 8, 8)] = 4; +// (*blocks)[ArrayTrans3D::vecToInd(7, 8, 8)] = 4; +// (*blocks)[ArrayTrans3D::vecToInd(7, 8, 7)] = 4; +// (*blocks)[ArrayTrans3D::vecToInd(8, 8, 7)] = 4; +// (*blocks)[ArrayTrans3D::vecToInd(8, 7, 8)] = 4; +// (*blocks)[ArrayTrans3D::vecToInd(7, 7, 8)] = 4; +// (*blocks)[ArrayTrans3D::vecToInd(7, 7, 7)] = 4; +// (*blocks)[ArrayTrans3D::vecToInd(8, 7, 7)] = 4; data->chunk = new BlockChunk(blocks); data->done = true; @@ -205,6 +218,7 @@ void World::handleMeshGenQueue() { } Timer t("Mesh Initialization"); + int meshUpdates = 0; for (auto iter = finishedMesh.begin(); iter != finishedMesh.end(); ) { if (t.elapsedNs() > 4000000) break; @@ -225,7 +239,10 @@ void World::handleMeshGenQueue() { iter = finishedMesh.erase(iter); delete threadData; + + meshUpdates++; } + lastMeshUpdates = meshUpdates; // t.printElapsedMs(); } diff --git a/zeus/game/world/World.h b/zeus/game/world/World.h index e36ccd8c..4ccd1571 100644 --- a/zeus/game/world/World.h +++ b/zeus/game/world/World.h @@ -81,6 +81,8 @@ public: return out; } + + int lastGenUpdates, lastMeshUpdates; private: //Global lists for storing blockChunks and meshChunks std::unordered_map blockChunks; diff --git a/zeus/server/Packet.cpp b/zeus/server/Packet.cpp new file mode 100644 index 00000000..05ef1099 --- /dev/null +++ b/zeus/server/Packet.cpp @@ -0,0 +1,87 @@ +// +// Created by aurailus on 10/01/19. +// + +#include +#include "Packet.h" + +Packet::Packet(Packet::PacketType p) { + this->type = p; +} + +//Convert a vector of PacketBytes (chars) into a PacketData by splitting the head and body information. +Packet Packet::deserialize(std::vector data) { + if (data.size() < 4) std::cerr << "Packet does not contain data." << std::endl; + + //Seperate the packet header from the body, + //This can be changed to support more header values in the future. + + //Determine Packet Type + int num = 0; + for (int i = 0; i < 4; i++) { + num <<= 8; + num |= data[i]; + } + + //Get body of the packet + std::vector dataBody; + dataBody.reserve(data.size() - 4); + + for (int i = 4; i < data.size(); i++) { + dataBody.push_back(data[i]); + } + + auto p = Packet(); + p.type = (PacketType)num; + p.length = dataBody.size(); + p.data = std::move(dataBody); + + return p; +} + +//Convert a PacketData into a serialized form to send over UDP. +std::vector Packet::serialize() { + std::vector data; + data.reserve(this->length + 4); + + //Encode Packet Type + encodeInt(data, (int)this->type); + + //Add body of the packet + for (PacketByte i : this->data) { + data.push_back(i); + } + + return data; +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wconversion" +void Packet::encodeInt(std::vector &target, int num) { + target.push_back((num >> 24) & 0xFF); + target.push_back((num >> 16) & 0xFF); + target.push_back((num >> 8) & 0xFF); + target.push_back((num) & 0xFF); +} +#pragma clang diagnostic pop + +int Packet::decodeInt(PacketByte* intStart) { + int num = 0; + for (int i = 0; i < 4; i++) { + num <<= 8; + num |= *(intStart++); + } + return num; +} + +void Packet::addIntegers(std::vector &integers) { + for (int i : integers) { + encodeInt(this->data, i); + } + this->length = data.size(); +} + +void Packet::addInt(int integer) { + encodeInt(this->data, integer); + this->length = data.size(); +} \ No newline at end of file diff --git a/zeus/server/Packet.h b/zeus/server/Packet.h new file mode 100644 index 00000000..a93aa41d --- /dev/null +++ b/zeus/server/Packet.h @@ -0,0 +1,39 @@ +// +// Created by aurailus on 10/01/19. +// + +#ifndef ZEUS_PACKET_H +#define ZEUS_PACKET_H + +#include + +class Packet { +public: + typedef unsigned long PacketType; + typedef unsigned char PacketByte; + + Packet() = default; + explicit Packet(PacketType p); + + void addIntegers(std::vector &integers); + void addInt(int integer); + + unsigned long length; + PacketType type; + std::vector data; + + ~Packet() = default; + + static Packet deserialize(std::vector data); + std::vector serialize(); + + static void encodeInt(std::vector &target, int num); + static int decodeInt(PacketByte* intStart); +public: + const static PacketType HANDSHAKE = 0; + const static PacketType AUTHENTICATE = 1; + const static PacketType KEEPALIVE = 2; +}; + + +#endif //ZEUS_PACKET_H diff --git a/zeus/server/Server.cpp b/zeus/server/Server.cpp new file mode 100644 index 00000000..ce7ba190 --- /dev/null +++ b/zeus/server/Server.cpp @@ -0,0 +1,51 @@ +// +// Created by aurailus on 09/01/19. +// + +#include "Server.h" + +Server::Server() = default; + +Server::Server(int port) { + //TODO: Use the port in the server initializer + this->port = port; + alive = true; +} + +void Server::start() { + server_socket = new asio::ip::udp::socket(io_context, udp::endpoint(udp::v4(), 12346)); + + while (alive) loop(); +} + +void Server::loop() { + + //Collect incoming packets + while (server_socket->available() > 0) { + size_t pendingSize = server_socket->available(); + std::vector recv_buf((unsigned long)pendingSize); + + auto remote_endpoint = new udp::endpoint(); + server_socket->receive_from(asio::buffer(recv_buf, pendingSize), *remote_endpoint); + + auto packet = Packet::deserialize(recv_buf); + if (packet.length > 0) handlePacket(packet, remote_endpoint); + } + + long sleep_for = 16L*1000000L; + std::this_thread::sleep_for(std::chrono::nanoseconds(sleep_for)); +} + +void Server::handlePacket(Packet &packet, udp::endpoint* endpoint) { + std::cout << packet.type << ", " << Packet::decodeInt(&packet.data[0]) << std::endl; +} + +void Server::cleanup() { + alive = false; + + delete server_socket; +} + +Server::~Server() { + cleanup(); +} \ No newline at end of file diff --git a/zeus/server/Server.h b/zeus/server/Server.h new file mode 100644 index 00000000..5ddba9b6 --- /dev/null +++ b/zeus/server/Server.h @@ -0,0 +1,41 @@ +// +// Created by aurailus on 09/01/19. +// + +#ifndef ZEUS_SERVER_H +#define ZEUS_SERVER_H + +#include +#include +#include "../engine/Timer.h" +#include "ClientConnection.h" +#include "Packet.h" +#include +#include + +using asio::ip::udp; + +class Server { +public: + Server(); + explicit Server(int port); + + void start(); + + ~Server(); +private: + void loop(); + void cleanup(); + + void handlePacket(Packet& packet, udp::endpoint* endpoint); + + std::map connections; + + int port; + bool alive; + asio::io_context io_context; + udp::socket* server_socket; +}; + + +#endif //ZEUS_SERVER_H