UDP Networking first commit + Bugfixes & Cleanup

New stuff:
* Client will fork and exec a given path with the "server" argument if supplied.
* Packet class to help transfer data between client and server.
* New Server class which accepts handshake from client
* GameScene now attempts to connect to a server and ends if it fails.

Fixes:
* Changed deltaTime to double on Player class
* SceneManager defaults Scene to nullptr to fix seg fault.
* Moved some code to DebugGui and out of GameScene.
* World class stores per-frame updates for chunks and meshes.
* Scene emits warning if a derived class doesn't override all methods.
* GameScene overrides cleanup
* Created MenuScene to test having multiple scenes.
* Moved commented code out of Main
master
aurailus 2019-01-10 23:33:36 -08:00
parent a681301ac6
commit c608e2336d
23 changed files with 546 additions and 147 deletions

View File

@ -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)

View File

@ -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"
}
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 59 KiB

View File

@ -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;
}

View File

@ -2,8 +2,13 @@
// Created by aurailus on 06/01/19.
//
#include <zconf.h>
#include <signal.h>
#include "Client.h"
#include "../game/GameScene.h"
#include "../server/Packet.h"
#include <asio.hpp>
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;

View File

@ -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;
};

View File

@ -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;
};

View File

@ -4,7 +4,9 @@
#include "SceneManager.h"
SceneManager::SceneManager() = default;
SceneManager::SceneManager() {
scene = nullptr;
};
void SceneManager::update() {
scene->update();

View File

@ -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");

View File

@ -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
}

View File

@ -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;

57
zeus/game/MenuScene.cpp Normal file
View File

@ -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;
}

29
zeus/game/MenuScene.h Normal file
View File

@ -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<Entity*> entities;
// DebugGui gui;
};
#endif //ZEUS_MENUSCENE_H

View File

@ -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<Entity*> &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;

View File

@ -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 <sstream>
class DebugGui {
@ -15,7 +17,7 @@ public:
DebugGui();
void pushGuiObjects(std::vector<Entity*> &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;

View File

@ -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;

View File

@ -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();
}

View File

@ -81,6 +81,8 @@ public:
return out;
}
int lastGenUpdates, lastMeshUpdates;
private:
//Global lists for storing blockChunks and meshChunks
std::unordered_map<glm::vec3, BlockChunk*, vec3cmp> blockChunks;

87
zeus/server/Packet.cpp Normal file
View File

@ -0,0 +1,87 @@
//
// Created by aurailus on 10/01/19.
//
#include <iostream>
#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<PacketByte> 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<PacketByte> 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::PacketByte> Packet::serialize() {
std::vector<PacketByte> 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<Packet::PacketByte> &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<int> &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();
}

39
zeus/server/Packet.h Normal file
View File

@ -0,0 +1,39 @@
//
// Created by aurailus on 10/01/19.
//
#ifndef ZEUS_PACKET_H
#define ZEUS_PACKET_H
#include <vector>
class Packet {
public:
typedef unsigned long PacketType;
typedef unsigned char PacketByte;
Packet() = default;
explicit Packet(PacketType p);
void addIntegers(std::vector<int> &integers);
void addInt(int integer);
unsigned long length;
PacketType type;
std::vector<PacketByte> data;
~Packet() = default;
static Packet deserialize(std::vector<PacketByte> data);
std::vector<Packet::PacketByte> serialize();
static void encodeInt(std::vector<PacketByte> &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

51
zeus/server/Server.cpp Normal file
View File

@ -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<Packet::PacketByte> 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();
}

41
zeus/server/Server.h Normal file
View File

@ -0,0 +1,41 @@
//
// Created by aurailus on 09/01/19.
//
#ifndef ZEUS_SERVER_H
#define ZEUS_SERVER_H
#include <thread>
#include <vector>
#include "../engine/Timer.h"
#include "ClientConnection.h"
#include "Packet.h"
#include <iostream>
#include <asio.hpp>
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<std::string, ClientConnection*> connections;
int port;
bool alive;
asio::io_context io_context;
udp::socket* server_socket;
};
#endif //ZEUS_SERVER_H