From f5aa7827af55342a1ec714d366944b3e3f3129b2 Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Wed, 21 Jun 2017 19:26:25 +0500 Subject: 2017-06-21 --- CMakeLists.txt | 25 +- include/AssetManager.hpp | 72 +++++ include/Core.hpp | 84 ++++++ include/GameState.hpp | 71 +++++ include/Nbt.hpp | 516 ++++++++++++++++++++++++++++++++++++ include/Utility.hpp | 55 ++++ include/Vector.hpp | 116 +++++++++ include/graphics/Gui.hpp | 7 + include/graphics/RenderSection.hpp | 41 +++ include/graphics/Shader.hpp | 24 ++ include/graphics/Texture.hpp | 14 + include/graphics/Widget.hpp | 8 + include/network/Network.hpp | 26 ++ include/network/NetworkClient.hpp | 26 ++ include/network/Packet.hpp | 521 +++++++++++++++++++++++++++++++++++++ include/network/Socket.hpp | 46 ++++ include/network/Stream.hpp | 107 ++++++++ include/world/Block.hpp | 15 ++ include/world/Collision.hpp | 8 + include/world/Section.hpp | 48 ++++ include/world/World.hpp | 35 +++ src/core/AssetManager.cpp | 3 +- src/core/AssetManager.hpp | 71 ----- src/core/Core.cpp | 307 ++-------------------- src/core/Core.hpp | 80 ------ src/gamestate/GameState.cpp | 389 --------------------------- src/gamestate/GameState.hpp | 70 ----- src/graphics/Gui.cpp | 1 + src/graphics/RenderSection.cpp | 281 ++++++++++++++++++++ src/graphics/Shader.cpp | 2 +- src/graphics/Shader.hpp | 22 -- src/graphics/Texture.cpp | 2 +- src/graphics/Texture.hpp | 14 - src/graphics/Widget.cpp | 1 + src/gui/Gui.cpp | 1 - src/gui/Gui.hpp | 7 - src/gui/Widget.cpp | 1 - src/gui/Widget.hpp | 8 - src/main.cpp | 2 +- src/nbt/Nbt.hpp | 515 ------------------------------------ src/network/Network.cpp | 3 +- src/network/Network.hpp | 26 -- src/network/NetworkClient.cpp | 3 +- src/network/NetworkClient.hpp | 25 -- src/network/Packet.hpp | 520 ------------------------------------ src/network/Socket.cpp | 2 +- src/network/Socket.hpp | 45 ---- src/network/Stream.cpp | 2 +- src/network/Stream.hpp | 115 -------- src/utility/Vector.hpp | 123 --------- src/utility/utility.cpp | 66 ----- src/utility/utility.h | 16 -- src/world/Block.cpp | 2 +- src/world/Block.hpp | 15 -- src/world/Collision.cpp | 2 +- src/world/Collision.hpp | 8 - src/world/GameState.cpp | 389 +++++++++++++++++++++++++++ src/world/Section.cpp | 16 +- src/world/Section.hpp | 43 --- src/world/World.cpp | 8 +- src/world/World.hpp | 37 --- 61 files changed, 2578 insertions(+), 2530 deletions(-) create mode 100644 include/AssetManager.hpp create mode 100644 include/Core.hpp create mode 100644 include/GameState.hpp create mode 100644 include/Nbt.hpp create mode 100644 include/Utility.hpp create mode 100644 include/Vector.hpp create mode 100644 include/graphics/Gui.hpp create mode 100644 include/graphics/RenderSection.hpp create mode 100644 include/graphics/Shader.hpp create mode 100644 include/graphics/Texture.hpp create mode 100644 include/graphics/Widget.hpp create mode 100644 include/network/Network.hpp create mode 100644 include/network/NetworkClient.hpp create mode 100644 include/network/Packet.hpp create mode 100644 include/network/Socket.hpp create mode 100644 include/network/Stream.hpp create mode 100644 include/world/Block.hpp create mode 100644 include/world/Collision.hpp create mode 100644 include/world/Section.hpp create mode 100644 include/world/World.hpp delete mode 100644 src/core/AssetManager.hpp delete mode 100644 src/core/Core.hpp delete mode 100644 src/gamestate/GameState.cpp delete mode 100644 src/gamestate/GameState.hpp create mode 100644 src/graphics/Gui.cpp create mode 100644 src/graphics/RenderSection.cpp delete mode 100644 src/graphics/Shader.hpp delete mode 100644 src/graphics/Texture.hpp create mode 100644 src/graphics/Widget.cpp delete mode 100644 src/gui/Gui.cpp delete mode 100644 src/gui/Gui.hpp delete mode 100644 src/gui/Widget.cpp delete mode 100644 src/gui/Widget.hpp delete mode 100644 src/nbt/Nbt.hpp delete mode 100644 src/network/Network.hpp delete mode 100644 src/network/NetworkClient.hpp delete mode 100644 src/network/Packet.hpp delete mode 100644 src/network/Socket.hpp delete mode 100644 src/network/Stream.hpp delete mode 100644 src/utility/Vector.hpp delete mode 100644 src/utility/utility.cpp delete mode 100644 src/utility/utility.h delete mode 100644 src/world/Block.hpp delete mode 100644 src/world/Collision.hpp create mode 100644 src/world/GameState.cpp delete mode 100644 src/world/Section.hpp delete mode 100644 src/world/World.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fb30f12..af0c9cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,20 +7,21 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # SOURCES ########## -set(SRC_CORE src/core/Core.hpp src/core/Core.cpp src/core/AssetManager.hpp src/core/AssetManager.cpp) -set(SRC_GAMESTATE src/gamestate/GameState.hpp src/gamestate/GameState.cpp) -set(SRC_GRAPHICS src/graphics/Texture.cpp src/graphics/Shader.cpp) -set(SRC_GUI src/gui/Gui.cpp src/gui/Widget.cpp) -set(SRC_NBT src/nbt/Nbt.hpp) -set(SRC_NETWORK src/network/Network.cpp src/network/NetworkClient.cpp src/network/Socket.cpp src/network/Stream.cpp - src/network/Packet.hpp) -set(SRC_UTILITY src/utility/Vector.hpp src/utility/utility.cpp) -set(SRC_WORLD src/world/Block.cpp src/world/Section.cpp src/world/World.cpp src/world/Collision.cpp src/world/Collision.hpp) +#[[set(SRC_CORE src/core/Core.cpp src/core/AssetManager.cpp) +set(SRC_GRAPHICS src/graphics/Texture.cpp src/graphics/Shader.cpp src/graphics/RenderSection.cpp src/graphics/Gui.cpp + src/graphics/Widget.cpp) +set(SRC_NBT include/Nbt.hpp) +set(SRC_NETWORK src/network/Network.cpp src/network/NetworkClient.cpp src/network/Socket.cpp src/network/Stream.cpp) +set(SRC_WORLD src/world/Block.cpp src/world/Section.cpp src/world/World.cpp src/world/Collision.cpp + src/world/GameState.cpp)*# -set(SOURCE_FILES src/main.cpp ${SRC_CORE} ${SRC_GAMESTATE} ${SRC_GRAPHICS} ${SRC_GUI} ${SRC_GRAPHICS} ${SRC_GUI} - ${SRC_NBT} ${SRC_NETWORK} ${SRC_UTILITY} ${SRC_WORLD}) +set(SOURCE_FILES src/main.cpp ${SRC_CORE} ${SRC_GRAPHICS} ${SRC_NETWORK} ${SRC_WORLD})]]# +file(GLOB_RECURSE SOURCES "./src/*.cpp") +file(GLOB_RECURSE HEADERS "./include/*.hpp") -add_executable(AltCraft ${SOURCE_FILES}) +add_executable(AltCraft ${HEADERS} ${SOURCES}) + +target_include_directories(AltCraft PUBLIC include/) ################ # CONFIGURATION diff --git a/include/AssetManager.hpp b/include/AssetManager.hpp new file mode 100644 index 0000000..f91c722 --- /dev/null +++ b/include/AssetManager.hpp @@ -0,0 +1,72 @@ +#pragma once + +#include +#include + +#include +#include +#include + +#include +#include + +struct TextureCoordinates { + TextureCoordinates(float x = -1, float y = -1, float w = -1, float h = -1) : x(x), y(y), w(w), h(h) {} + + bool operator==(const TextureCoordinates &rhs) const { + return x == rhs.x && + y == rhs.y && + w == rhs.w && + h == rhs.h; + } + + explicit operator bool() const { + return !(*this == TextureCoordinates(-1, -1, -1, -1)); + } + + float x, y, w, h; +}; + +struct BlockTextureId { + //Block sides: 0 - bottom, 1 - top, 2 - north, 3 - south, 4 - west, 5 - east 6 - every side + BlockTextureId(int id = 0, int state = 0, int side = 6) : id(id), state(state), side(side) {} + + int id:9; + int state:4; + int side:3; + + + bool operator<(const BlockTextureId &rhs) const { + if (id < rhs.id) + return true; + if (rhs.id < id) + return false; + if (state < rhs.state) + return true; + if (rhs.state < state) + return false; + return side < rhs.side; + } +}; + +class AssetManager { + Texture *textureAtlas; + std::map assetIds; + std::map assetTextures; +public: + AssetManager(); + + ~AssetManager(); + + void LoadTextureResources(); + + TextureCoordinates GetTextureByAssetName(std::string AssetName); + + std::string GetTextureAssetNameByBlockId(BlockTextureId block); + + GLuint GetTextureAtlas(); + + void LoadIds(); + + TextureCoordinates GetTextureByBlock(BlockTextureId block); +}; diff --git a/include/Core.hpp b/include/Core.hpp new file mode 100644 index 0000000..64fab4e --- /dev/null +++ b/include/Core.hpp @@ -0,0 +1,84 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +class Core { + GameState *gameState; + NetworkClient *client; + sf::Window *window; + AssetManager *assetManager; + bool isMouseCaptured = false; + bool isRunning = true; + enum { + MainMenu, + Loading, + Playing, + PauseMenu, + } currentState = Playing; + float mouseXDelta, mouseYDelta; + float deltaTime; + float absTime; + + void RenderWorld(); + + void HandleMouseCapture(); + + void HandleEvents(); + + void InitSfml(unsigned int WinWidth, unsigned int WinHeight, std::string WinTitle); + + void InitGlew(); + + void SetMouseCapture(bool IsCaptured); + + void PrepareToRendering(); + + void RenderFrame(); + + unsigned int width(); + + unsigned int height(); + + void UpdateChunksToRender(); + + void UpdateGameState(); + + std::thread gameStateLoopThread; + + Shader *shader; + //Cube verticies, Cube VAO, Cube UVs, TextureIndexes UboTextureIndexes, TextureData UboTextureIndexes, TextureData2 UboTextureIndexes, Blocks VBO, Models VBO, Line VAO, Lines VBO + //GLuint VBO, VAO, VBO2, UboTextureIndexes, UboTextureData, VBO3, VBO4, VAO2, VBO5; + GLuint UboTextureIndexes, UboTextureData; + //std::vector toRender; + std::vector toRender; + std::map availableChunks; + + int ChunkDistance = 2; + + RenderState renderState; + + /*std::map> toRenderModels; + std::map> toRenderBlocks;*/ + + double tickRate = 0; + +public: + Core(); + + ~Core(); + + void Exec(); +}; diff --git a/include/GameState.hpp b/include/GameState.hpp new file mode 100644 index 0000000..6741882 --- /dev/null +++ b/include/GameState.hpp @@ -0,0 +1,71 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include + +class GameState { + NetworkClient *nc; +public: + GameState(NetworkClient *NetClient, bool &quit); + + void Update(float deltaTime); + + //Navigation + enum Direction { + FORWARD, BACKWARD, LEFT, RIGHT, JUMP + }; + void HandleMovement(GameState::Direction direction, float deltaTime); + void HandleRotation(double yaw, double pitch); + glm::mat4 GetViewMatrix(); + void updateCameraVectors(); + + float Yaw(); + float Pitch(); + void SetYaw(float yaw); + void SetPitch(float pitch); + + glm::vec3 Position(); + void SetPosition(glm::vec3 Position); + glm::vec3 Front; + glm::vec3 Up; + glm::vec3 Right; + glm::vec3 WorldUp; + + //Everything other + World world; + bool &isRunning; + + std::string g_PlayerUuid; + std::string g_PlayerName; + bool g_IsGameStarted; + int g_PlayerEid; + int g_Gamemode; + int g_Dimension; + byte g_Difficulty; + byte g_MaxPlayers; + std::string g_LevelType; + bool g_ReducedDebugInfo; + Vector g_SpawnPosition; + bool g_PlayerInvulnerable; + bool g_PlayerFlying; + bool g_PlayerAllowFlying; + bool g_PlayerCreativeMode; + float g_PlayerFlyingSpeed; + float g_PlayerFovModifier; + float g_PlayerPitch; + float g_PlayerYaw; + double g_PlayerX; + double g_PlayerY; + double g_PlayerZ; + float g_PlayerHealth; + + bool g_OnGround = true; + double g_PlayerVelocityX = 0; + double g_PlayerVelocityY = 0; + double g_PlayerVelocityZ = 0; +}; diff --git a/include/Nbt.hpp b/include/Nbt.hpp new file mode 100644 index 0000000..03f5af0 --- /dev/null +++ b/include/Nbt.hpp @@ -0,0 +1,516 @@ +#pragma once + +#include +#include +#include +#include + +#include + +namespace nbt { + enum TagType { + End, //nullptr + Byte, //int8_t + Short, //int16_t + Int, //int32_t + Long, //int64_t + Float, //float + Double, //double + ByteArray, //std::vector + String, //std::string + List, //std::vector + Compound, //std::vector + IntArray, //std::vector + Unknown, //dummy value + }; + + class NbtTag; + + typedef std::vector compound_t; + + typedef std::string string_t; + + typedef std::vector byteArray_t; + + typedef std::vector intArray_t; + + class NbtTag { + TagType type = Unknown; + string_t name = ""; + unsigned char *data = nullptr; + public: + NbtTag(TagType type, string_t name) : type(type), name(name) { + switch (type) { + case End: + data = nullptr; + break; + case Compound: + data = (unsigned char *) new compound_t; + break; + case String: + data = (unsigned char *) new string_t; + break; + case Int: + data = (unsigned char *) new int32_t; + break; + case Long: + data = (unsigned char *) new int64_t; + break; + case Byte: + data = (unsigned char *) new int8_t; + break; + case Short: + data = (unsigned char *) new int16_t; + break; + case Float: + data = (unsigned char *) new float; + break; + case Double: + data = (unsigned char *) new double; + break; + case ByteArray: + data = (unsigned char *) new byteArray_t; + break; + case List: + data = (unsigned char *) new compound_t; + break; + case IntArray: + data = (unsigned char *) new intArray_t; + } + } + + NbtTag(const NbtTag &other) : type(other.type), name(other.name) { + switch (type) { + case Byte: + data = (unsigned char *) new int8_t; + *((int8_t *) data) = *((int8_t *) other.data); + break; + case Short: + data = (unsigned char *) new int16_t; + *((int16_t *) data) = *((int16_t *) other.data); + break; + case Int: + data = (unsigned char *) new int32_t; + *((int32_t *) data) = *((int32_t *) other.data); + break; + case Long: + data = (unsigned char *) new int64_t; + *((int64_t *) data) = *((int64_t *) other.data); + break; + case Float: + data = (unsigned char *) new float; + *((float *) data) = *((float *) other.data); + break; + case Double: + data = (unsigned char *) new double; + *((double *) data) = *((double *) other.data); + break; + case ByteArray: + data = (unsigned char *) new byteArray_t; + *((std::vector *) data) = *((std::vector *) other.data); + break; + case String: + data = (unsigned char *) new string_t; + *((std::string *) data) = *((std::string *) other.data); + break; + case List: + data = (unsigned char *) new compound_t; + *((std::vector *) data) = *((std::vector *) other.data); + break; + case Compound: + data = (unsigned char *) new compound_t; + *((std::vector *) data) = *((std::vector *) other.data); + break; + case IntArray: + data = (unsigned char *) new intArray_t; + *((std::vector *) data) = *((std::vector *) other.data); + break; + } + } + + ~NbtTag() { + switch (type) { + case Byte: + delete ((int8_t *) data); + break; + case Short: + delete ((int16_t *) data); + break; + case Int: + delete ((int32_t *) data); + break; + case Long: + delete ((int64_t *) data); + break; + case Float: + delete ((float *) data); + break; + case Double: + delete ((double *) data); + break; + case ByteArray: + delete ((std::vector *) data); + break; + case String: + delete ((std::string *) data); + break; + case List: + delete ((std::vector *) data); + break; + case Compound: + delete ((std::vector *) data); + break; + case IntArray: + delete ((std::vector *) data); + break; + } + }; + + void swap(NbtTag &other) { + std::swap(other.data, data); + std::swap(other.name, name); + std::swap(other.type, type); + } + + NbtTag &operator=(NbtTag other) { + other.swap(*this); + return *this; + } + + TagType GetType() const { + return type; + } + + string_t GetName() const { + return name; + } + + + string_t &GetString() { + string_t &val = *reinterpret_cast(data); + return val; + } + + compound_t &GetCompound() { + std::vector &val = *reinterpret_cast *>(data); + return val; + } + + compound_t &GetList() { + std::vector &val = *reinterpret_cast *>(data); + return val; + } + + int64_t &GetLong() { + int64_t &val = *reinterpret_cast(data); + return val; + } + + float &GetFloat() { + float &val = *reinterpret_cast(data); + return val; + } + + double &GetDouble() { + double &val = *reinterpret_cast(data); + return val; + } + + byteArray_t &GetByteArray() { + auto &val = *reinterpret_cast(data); + return val; + } + + intArray_t &GetIntArray() { + auto &val = *reinterpret_cast(data); + return val; + } + + int16_t &GetShort() { + auto &val = *reinterpret_cast(data); + return val; + } + + int32_t &GetInt() { + auto &val = *reinterpret_cast(data); + return val; + } + + int8_t &GetByte() { + auto &val = *reinterpret_cast(data); + return val; + } + }; + + NbtTag ParseTag(unsigned char *data, size_t &size, TagType listItemType = Unknown) { + size = 0; + TagType type; + if (listItemType == Unknown) { + type = (TagType) *data; + data += 1; + size += 1; + } else + type = listItemType; + string_t name; + if (listItemType == Unknown && type != End) { + short nameLen = *((short *) data); + data += 2; + size += 2; + endswap(&nameLen); + name = std::string((char *) data, nameLen); + data += nameLen; + size += nameLen; + } + NbtTag tag(type, name); + switch (type) { + case Compound: { + do { + size_t s; + tag.GetCompound().push_back(ParseTag(data, s)); + data += s; + size += s; + } while (tag.GetCompound().back().GetType() != End); + tag.GetCompound().pop_back(); + return tag; + } + case String: { + short len = *((short *) data); + data += 2; + size += 2; + endswap(&len); + string_t str((char *) data, len); + data += len; + size += len; + tag.GetString() = str; + return tag; + } + case End: + return tag; + case Long: + tag.GetLong() = *((int64_t *) data); + endswap(&tag.GetLong()); + data += 8; + size += 8; + return tag; + case Short: + tag.GetShort() = *((int16_t *) data); + endswap(&tag.GetShort()); + data += 2; + size += 2; + return tag; + case Float: + tag.GetFloat() = *((float *) data); + endswap(&tag.GetFloat()); + data += 4; + size += 4; + return tag; + case Double: + tag.GetDouble() = *((double *) data); + endswap(&tag.GetDouble()); + data += 8; + size += 8; + return tag; + case Byte: + tag.GetByte() = *((int8_t *) data); + endswap(&tag.GetByte()); + data += 1; + size += 1; + return tag; + case Int: + tag.GetInt() = *((int32_t *) data); + endswap(&tag.GetInt()); + data += 4; + size += 4; + return tag; + case List: { + TagType listType = *((TagType *) data); + data += 1; + size += 1; + int32_t listLength = *((int32_t *) data); + endswap(&listLength); + data += 4; + size += 4; + for (int i = 0; i < listLength; i++) { + size_t s = 0; + std::vector &vec = tag.GetCompound(); + vec.push_back(ParseTag(data, s, listType)); + data += s; + size += s; + } + return tag; + } + case ByteArray: { + int32_t arrLength = *((int32_t *) data); + endswap(&arrLength); + data += 4; + size += 4; + for (int i = 0; i < arrLength; i++) { + signed char val = (signed char) data[i]; + std::vector &vec = tag.GetByteArray(); + vec.push_back(val); + } + data += arrLength; + size += arrLength; + return tag; + } + default: + throw 13; + } + } + + NbtTag ParseTag(unsigned char *data, size_t *optionalSize = nullptr) { + size_t s = 0; + size_t &size = (optionalSize ? *optionalSize : s); + return ParseTag(data, size); + } + + std::vector Decompress(unsigned char *data, size_t dataLen) { + const size_t decompBuffSize = 1024 * 16; + unsigned char *decompBuff = new unsigned char[decompBuffSize]; + std::vector uncompressed; + for (int i = 0; i < decompBuffSize; i++) + decompBuff[i] = 0; + + + z_stream stream; + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.next_in = data; + stream.avail_in = dataLen; + stream.next_out = decompBuff; + stream.avail_out = decompBuffSize; + + if (inflateInit2(&stream, 15 + 32) != Z_OK) { + delete[] decompBuff; + throw 171; + } + + int res; + do { + stream.avail_out = decompBuffSize; + + switch ((res = inflate(&stream, Z_NO_FLUSH))) { + case Z_MEM_ERROR: + throw 172; + case Z_DATA_ERROR: + throw 173; + case Z_NEED_DICT: + throw 174; + } + + uncompressed.resize(uncompressed.size() + decompBuffSize); + std::copy(decompBuff, decompBuff + decompBuffSize, uncompressed.end() - decompBuffSize); + } while (stream.avail_out == 0); + if (res != Z_STREAM_END) + throw 175; + if (inflateEnd(&stream) != Z_OK) + throw 176; + delete[] decompBuff; + return uncompressed; + } + + NbtTag ParseCompressed(unsigned char *data, size_t dataLen) { + auto uncompressed = Decompress(data, dataLen); + NbtTag root = ParseTag(uncompressed.data()); + return root; + } + + NbtTag Parse(unsigned char *data, size_t dataLen) { + bool isCompressed = *data != 10; + if (isCompressed) + return ParseCompressed(data, dataLen); + else + return ParseTag(data); + } + + void PrintTree(NbtTag &tree, int deepness = 0, std::ostream &ostream = std::cout) { + ostream << std::string(deepness, '\t') << "Tag "; + switch (tree.GetType()) { + case Byte: + ostream << "byte"; + break; + case Short: + ostream << "short"; + break; + case Int: + ostream << "int"; + break; + case Long: + ostream << "long"; + break; + case Float: + ostream << "float"; + break; + case Double: + ostream << "double"; + break; + case ByteArray: + ostream << "byte array"; + break; + case String: + ostream << "string"; + break; + case List: + ostream << "list"; + break; + case Compound: + ostream << "compound"; + break; + case IntArray: + ostream << "int array"; + break; + case End: + ostream << "end"; + break; + } + if (tree.GetName().length() > 0) + ostream << " (" << tree.GetName() << ")"; + ostream << ": "; + + if (tree.GetType() == Compound || tree.GetType() == List) { + std::vector &vec = (tree.GetType() == Compound ? tree.GetCompound() : tree.GetList()); + ostream << vec.size() << " entries {" << std::endl; + for (auto it = vec.begin(); it != vec.end(); ++it) { + PrintTree(*it, deepness + 1, std::cout); + } + ostream << std::string(deepness, '\t') << "}" << std::endl; + return; + } else { + switch (tree.GetType()) { + case Int: + ostream << tree.GetInt(); + break; + case String: + ostream << "\"" << tree.GetString() << "\""; + break; + case Double: + ostream << tree.GetDouble(); + break; + case Float: + ostream << tree.GetFloat(); + break; + case Short: + ostream << tree.GetShort(); + break; + case Byte: + ostream << (int) tree.GetByte(); + break; + case Long: + ostream << tree.GetLong(); + break; + case ByteArray: + ostream << "[" << tree.GetByteArray().size() << " bytes]: "; + for (int i = 0; i < (tree.GetByteArray().size() > 10 ? 10 : tree.GetByteArray().size()); i++) { + ostream << std::hex << "0x" << (tree.GetByteArray()[i] > 15 ? "" : "0") + << (int) tree.GetByteArray()[i] + << std::dec << " "; + } + break; + case IntArray: + break; + } + ostream << std::endl; + } + } +} \ No newline at end of file diff --git a/include/Utility.hpp b/include/Utility.hpp new file mode 100644 index 0000000..92e924f --- /dev/null +++ b/include/Utility.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include + +#include + +template +void endswap(T *objp) { + unsigned char *memp = reinterpret_cast(objp); + std::reverse(memp, memp + sizeof(T)); +} + +template +void endswap(T &obj) { + unsigned char *raw = reinterpret_cast(&obj); + std::reverse(raw, raw + sizeof(T)); +} + +inline void endswap(unsigned char *arr, size_t arrLen) { + std::reverse(arr, arr + arrLen); +} + +inline GLenum glCheckError_(const char *file, int line) { + GLenum errorCode; + while ((errorCode = glGetError()) != GL_NO_ERROR) { + std::string error; + switch (errorCode) { + case GL_INVALID_ENUM: + error = "INVALID_ENUM"; + break; + case GL_INVALID_VALUE: + error = "INVALID_VALUE"; + break; + case GL_INVALID_OPERATION: + error = "INVALID_OPERATION"; + break; + case GL_STACK_OVERFLOW: + error = "STACK_OVERFLOW"; + break; + case GL_STACK_UNDERFLOW: + error = "STACK_UNDERFLOW"; + break; + case GL_OUT_OF_MEMORY: + error = "OUT_OF_MEMORY"; + break; + case GL_INVALID_FRAMEBUFFER_OPERATION: + error = "INVALID_FRAMEBUFFER_OPERATION"; + break; + } + LOG(ERROR) << "OpenGL error: " << error << " at " << file << ":" << line; + } + return errorCode; +} + +#define glCheckError() glCheckError_(__FILE__, __LINE__) \ No newline at end of file diff --git a/include/Vector.hpp b/include/Vector.hpp new file mode 100644 index 0000000..a2d5c6a --- /dev/null +++ b/include/Vector.hpp @@ -0,0 +1,116 @@ +#pragma once + +#include +#include +#include + +#include + +template +class Vector3 { + T x, y, z; +public: + Vector3(T X = 0, T Y = 0, T Z = 0) : x(X), y(Y), z(Z) {} + + Vector3(const Vector3 &rhs) : x(rhs.x), y(rhs.y), z(rhs.z) {} + + ~Vector3() = default; + + void SetX(T X) { x = X; } + + void SetY(T Y) { y = Y; } + + void SetZ(T Z) { z = Z; } + + T GetX() const { return x; } + + T GetY() const { return y; } + + T GetZ() const { return z; } + + double GetMagnitude() const { return std::sqrt(std::pow(x, 2) + std::pow(y, 2) + std::pow(z, 2)); } + + operator glm::vec3() const { + return glm::vec3(x, y, z); + } + + void swap(Vector3 &rhs) { + std::swap(x, rhs.x); + std::swap(y, rhs.y); + std::swap(z, rhs.z); + } + + Vector3 &operator=(Vector3 rhs) { + rhs.swap(*this); + return *this; + } + + Vector3 operator*(T rhs) const { + return Vector3( + x * rhs, + y * rhs, + z * rhs + ); + } + + Vector3 operator/(T rhs) const { + return Vector3( + x / rhs, + y / rhs, + z / rhs + ); + } + + Vector3 operator+(const Vector3 &rhs) const { + return Vector3( + x + rhs.x, + y + rhs.y, + z + rhs.z + ); + } + + Vector3 operator-(const Vector3 &rhs) const { + return Vector3( + x - rhs.x, + y - rhs.y, + z - rhs.z + ); + } + + Vector3 operator*(const Vector3 &rhs) const { + return Vector3( + x * rhs.x, + y * rhs.y, + z * rhs.z + ); + } + + Vector3 operator/(const Vector3 &rhs) const { + return Vector3( + x / rhs.x, + y / rhs.y, + z / rhs.z + ); + } + + bool operator==(const Vector3 &rhs) const { + return (x == rhs.x && y == rhs.y && z == rhs.z); + } + + bool operator!=(const Vector3 &rhs) const { + return !(*this == rhs); + } + + bool operator<(const Vector3 &rhs) const { + return std::tie(x, y, z) < std::tie(rhs.x, rhs.y, rhs.z); + } + + + friend std::ostream &operator<<(std::ostream &os, const Vector3 &vector3) { + os << vector3.x << ", " << vector3.y << ", " << vector3.z; + return os; + } +}; + +typedef Vector3 VectorF; +typedef Vector3 Vector; \ No newline at end of file diff --git a/include/graphics/Gui.hpp b/include/graphics/Gui.hpp new file mode 100644 index 0000000..641b941 --- /dev/null +++ b/include/graphics/Gui.hpp @@ -0,0 +1,7 @@ +#pragma once + +class Gui { + +public: + int WHY=0; +}; diff --git a/include/graphics/RenderSection.hpp b/include/graphics/RenderSection.hpp new file mode 100644 index 0000000..6a2f3ce --- /dev/null +++ b/include/graphics/RenderSection.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +class RenderState { + GLuint ActiveVao; + GLuint ActiveShader; +public: + void SetActiveVao(GLuint Vao); + void SetActiveShader(GLuint Shader); +}; + +class RenderSection { + Vector sectionPosition; + World *world; + GLuint Vao,VboBlocks,VboModels; + + static GLuint VboVertices,VboUvs; + static std::map refCounterVbo; + static std::map refCounterVao; + + size_t numOfBlocks; + +public: + RenderSection(World *world, Vector position); + RenderSection(const RenderSection &other); + ~RenderSection(); + + void UpdateState(); + void Render(RenderState &state); + + Section* GetSection(); +}; \ No newline at end of file diff --git a/include/graphics/Shader.hpp b/include/graphics/Shader.hpp new file mode 100644 index 0000000..17a434e --- /dev/null +++ b/include/graphics/Shader.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include + +#include +#include + +class Shader +{ +private: + const GLchar *vertex; + const GLchar *fragment; +public: + // Идентификатор программы + GLuint Program; + // Конструктор считывает и собирает шейдер + Shader(const GLchar* vertexPath, const GLchar* fragmentPath, const GLchar* geometryPath = nullptr); + // Использование программы + void Use(); + + void Reload(); +}; \ No newline at end of file diff --git a/include/graphics/Texture.hpp b/include/graphics/Texture.hpp new file mode 100644 index 0000000..277806a --- /dev/null +++ b/include/graphics/Texture.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include +#include +#include + +class Texture { + Texture(Texture&); + Texture&operator=(Texture&); +public: + GLuint texture; + Texture(std::string filename, GLenum textureWrapping = GL_CLAMP_TO_BORDER, GLenum textureFiltering = GL_NEAREST); + ~Texture(); +}; \ No newline at end of file diff --git a/include/graphics/Widget.hpp b/include/graphics/Widget.hpp new file mode 100644 index 0000000..c4d5dc1 --- /dev/null +++ b/include/graphics/Widget.hpp @@ -0,0 +1,8 @@ +#pragma once + +class Widget { + unsigned int x,y,w,h; +public: + Widget(Widget *parent); + ~Widget(); +}; diff --git a/include/network/Network.hpp b/include/network/Network.hpp new file mode 100644 index 0000000..1281289 --- /dev/null +++ b/include/network/Network.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include +#include "Socket.hpp" +#include "Packet.hpp" + +enum ConnectionState { + Handshaking, + Login, + Play, + Status, +}; + +class Network { + Socket *socket; + StreamSocket *stream; + + std::shared_ptr ReceivePacketByPacketId(int packetId, ConnectionState state, StreamInput &stream); +public: + Network(std::string address, unsigned short port); + ~Network(); + + std::shared_ptr ReceivePacket(ConnectionState state = Play); + void SendPacket(Packet &packet); + std::shared_ptr ParsePacketPlay(PacketNamePlayCB id); +}; \ No newline at end of file diff --git a/include/network/NetworkClient.hpp b/include/network/NetworkClient.hpp new file mode 100644 index 0000000..22b1b22 --- /dev/null +++ b/include/network/NetworkClient.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include +#include +#include + +#include + +class NetworkClient { + Network network; + std::thread networkThread; + std::mutex toSendMutex; + std::mutex toReceiveMutex; + std::queue > toSend; + std::queue > toReceive; + bool isActive=true; + bool &isRunning; + ConnectionState state; + void NetworkLoop(); +public: + NetworkClient(std::string address, unsigned short port, std::string username, bool &quit); + ~NetworkClient(); + + std::shared_ptr ReceivePacket(); + void SendPacket(std::shared_ptr packet); +}; \ No newline at end of file diff --git a/include/network/Packet.hpp b/include/network/Packet.hpp new file mode 100644 index 0000000..685e3da --- /dev/null +++ b/include/network/Packet.hpp @@ -0,0 +1,521 @@ +#pragma once + +#include + +#include + +enum PacketNameLoginSB { + LoginStart = 0x00, + EncryptionResponse = 0x01, +}; +enum PacketNamePlaySB { + TeleportConfirm, + PrepareCraftingGrid, + TabCompleteSB, + ChatMessageSB, + ClientStatus, + ClientSettings, + ConfirmTransactionSB, + EnchantItem, + ClickWindow, + CloseWindowSB, + PluginMessageSB, + UseEntity, + KeepAliveSB, + Player, + PlayerPosition, + PlayerPositionAndLookSB, + PlayerLook, + VehicleMoveSB, + SteerBoat, + PlayerAbilitiesSB, + PlayerDigging, + EntityAction, + SteerVehicle, + CraftingBookData, + ResourcePackStatus, + AdvancementTab, + HeldItemChangeSB, + CreativeInventoryAction, + UpdateSign, + AnimationSB, + Spectate, + PlayerBlockPlacement, + UseItem, +}; + +enum PacketNameHandshakingCB { + Handshake = 0x00, +}; +enum PacketNameLoginCB { + Disconnect = 0x00, + EncryptionRequest = 0x01, + LoginSuccess = 0x02, + SetCompression = 0x03, +}; +enum PacketNamePlayCB { + SpawnObject = 0x00, + SpawnExperienceOrb, + SpawnGlobalEntity, + SpawnMob, + SpawnPainting, + SpawnPlayer, + AnimationCB, + Statistics, + BlockBreakAnimation, + UpdateBlockEntity, + BlockAction, + BlockChange, + BossBar, + ServerDifficulty, + TabCompleteCB, + ChatMessageCB, + MultiBlockChange, + ConfirmTransactionCB, + CloseWindowCB, + OpenWindow, + WindowItems, + WindowProperty, + SetSlot, + SetCooldown, + PluginMessageCB, + NamedSoundEffect, + DisconnectPlay, + EntityStatus, + Explosion, + UnloadChunk, + ChangeGameState, + KeepAliveCB, + ChunkData, + Effect, + Particle, + JoinGame, + Map, + EntityRelativeMove, + EntityLookAndRelativeMove, + EntityLook, + Entity, + VehicleMove, + OpenSignEditor, + PlayerAbilitiesCB, + CombatEvent, + PlayerListItem, + PlayerPositionAndLookCB, + UseBed, + UnlockRecipes, + DestroyEntities, + RemoveEntityEffect, + ResourcePackSend, + Respawn, + EntityHeadLook, + SelectAdvancementTab, + WorldBorder, + Camera, + HeldItemChangeCB, + DisplayScoreboard, + EntityMetadata, + AttachEntity, + EntityVelocity, + EntityEquipment, + SetExperience, + UpdateHealth, + ScoreboardObjective, + SetPassengers, + Teams, + UpdateScore, + SpawnPosition, + TimeUpdate, + Title, + SoundEffect, + PlayerListHeaderAndFooter, + CollectItem, + EntityTeleport, + Advancements, + EntityProperties, + EntityEffect, +}; + +struct Packet { + virtual ~Packet() = default; + virtual void ToStream(StreamOutput *stream) = 0; + virtual void FromStream(StreamInput *stream) = 0; + virtual int GetPacketId() = 0; +}; + +struct PacketHandshake : Packet { + void ToStream(StreamOutput *stream) override { + stream->WriteVarInt(protocolVersion); + stream->WriteString(serverAddress); + stream->WriteUShort(serverPort); + stream->WriteVarInt(nextState); + } + + void FromStream(StreamInput *stream) override { + protocolVersion = stream->ReadVarInt(); + serverAddress = stream->ReadString(); + serverPort = stream->ReadUShort(); + nextState = stream->ReadVarInt(); + } + + int GetPacketId() override { + return PacketNameHandshakingCB::Handshake; + } + + int protocolVersion; + std::string serverAddress; + unsigned short serverPort; + int nextState; +}; + +struct PacketLoginStart : Packet { + void ToStream(StreamOutput *stream) override { + stream->WriteString(Username); + } + + void FromStream(StreamInput *stream) override { + Username = stream->ReadString(); + } + + int GetPacketId() override { + return PacketNameLoginSB::LoginStart; + } + + std::string Username; +}; + +struct PacketLoginSuccess : Packet { + void ToStream(StreamOutput *stream) override { + stream->WriteString(Uuid); + stream->WriteString(Username); + } + + void FromStream(StreamInput *stream) override { + Uuid = stream->ReadString(); + Username = stream->ReadString(); + } + + int GetPacketId() override { + return PacketNameLoginCB::LoginSuccess; + } + + std::string Uuid; + std::string Username; +}; + +struct PacketJoinGame : Packet { + void ToStream(StreamOutput *stream) override { + stream->WriteInt(EntityId); + stream->WriteUByte(Gamemode); + stream->WriteInt(Dimension); + stream->WriteUByte(Difficulty); + stream->WriteUByte(MaxPlayers); + stream->WriteString(LevelType); + stream->WriteBool(ReducedDebugInfo); + } + + void FromStream(StreamInput *stream) override { + EntityId = stream->ReadInt(); + Gamemode = stream->ReadUByte(); + Dimension = stream->ReadInt(); + Difficulty = stream->ReadUByte(); + MaxPlayers = stream->ReadUByte(); + LevelType = stream->ReadString(); + ReducedDebugInfo = stream->ReadBool(); + } + + int GetPacketId() override { + return PacketNamePlayCB::JoinGame; + } + + int EntityId; + unsigned char Gamemode; + int Dimension; + unsigned char Difficulty; + unsigned char MaxPlayers; + std::string LevelType; + bool ReducedDebugInfo; +}; + +struct PacketDisconnectPlay : Packet { + void ToStream(StreamOutput *stream) override { + stream->WriteString(Reason); //TODO: Implement chat-wrapper + } + + void FromStream(StreamInput *stream) override { + Reason = stream->ReadChat(); + } + + int GetPacketId() override { + return PacketNamePlayCB::DisconnectPlay; + } + + std::string Reason; +}; + +struct PacketSpawnPosition : Packet { + void ToStream(StreamOutput *stream) override { + stream->WritePosition(Location); + } + + void FromStream(StreamInput *stream) override { + Location = stream->ReadPosition(); + } + + int GetPacketId() override { + return PacketNamePlayCB::SpawnPosition; + } + + Vector Location; +}; + +struct PacketKeepAliveCB : Packet { + void ToStream(StreamOutput *stream) override { + stream->WriteVarInt(KeepAliveId); + } + + void FromStream(StreamInput *stream) override { + KeepAliveId = stream->ReadVarInt(); + } + + int GetPacketId() override { + return PacketNamePlayCB::KeepAliveCB; + } + + int KeepAliveId; +}; + +struct PacketKeepAliveSB : Packet { + void ToStream(StreamOutput *stream) override { + stream->WriteVarInt(KeepAliveId); + } + + void FromStream(StreamInput *stream) override { + KeepAliveId = stream->ReadVarInt(); + } + + int GetPacketId() override { + return PacketNamePlaySB::KeepAliveSB; + } + + int KeepAliveId; + + PacketKeepAliveSB(int KeepAliveId) : KeepAliveId(KeepAliveId) {} +}; + +struct PacketPlayerPositionAndLookCB : Packet { + void ToStream(StreamOutput *stream) override { + stream->WriteDouble(X); + stream->WriteDouble(Y); + stream->WriteDouble(Z); + stream->WriteFloat(Yaw); + stream->WriteFloat(Pitch); + stream->WriteUByte(Flags); + stream->WriteVarInt(TeleportId); + } + + void FromStream(StreamInput *stream) override { + X = stream->ReadDouble(); + Y = stream->ReadDouble(); + Z = stream->ReadDouble(); + Yaw = stream->ReadFloat(); + Pitch = stream->ReadFloat(); + Flags = stream->ReadUByte(); + TeleportId = stream->ReadVarInt(); + } + + int GetPacketId() override { + return PacketNamePlayCB::PlayerPositionAndLookCB; + } + + double X; + double Y; + double Z; + float Yaw; + float Pitch; + unsigned char Flags; + int TeleportId; +}; + +struct PacketTeleportConfirm : Packet { + void ToStream(StreamOutput *stream) override { + stream->WriteVarInt(TeleportId); + } + + void FromStream(StreamInput *stream) override { + TeleportId = stream->ReadVarInt(); + } + + int GetPacketId() override { + return PacketNamePlaySB::TeleportConfirm; + } + + int TeleportId; + + PacketTeleportConfirm(int TeleportId) : TeleportId(TeleportId) {} +}; + +struct PacketClientStatus : Packet { + void ToStream(StreamOutput *stream) override { + stream->WriteVarInt(ActionId); + } + + void FromStream(StreamInput *stream) override { + ActionId = stream->ReadVarInt(); + } + + int GetPacketId() override { + return PacketNamePlaySB::ClientStatus; + } + + int ActionId; + + PacketClientStatus(int ActionId) : ActionId(ActionId) {} +}; + +struct PacketPlayerPositionAndLookSB : Packet { + void ToStream(StreamOutput *stream) override { + stream->WriteDouble(X); + stream->WriteDouble(FeetY); + stream->WriteDouble(Z); + stream->WriteFloat(Yaw); + stream->WriteFloat(Pitch); + stream->WriteBool(OnGround); + } + + void FromStream(StreamInput *stream) override { + X = stream->ReadDouble(); + FeetY = stream->ReadDouble(); + Z = stream->ReadDouble(); + Yaw = stream->ReadFloat(); + Pitch = stream->ReadFloat(); + OnGround = stream->ReadBool(); + } + + int GetPacketId() override { + return PacketNamePlaySB::PlayerPositionAndLookSB; + } + + + double X; + double FeetY; + double Z; + float Yaw; + float Pitch; + bool OnGround; + + PacketPlayerPositionAndLookSB(double X, double FeetY, double Z, + float Yaw, float Pitch, bool OnGround) : X(X), FeetY(FeetY), Z(Z), Yaw(Yaw), + Pitch(Pitch), OnGround(OnGround) {} +}; + +struct PacketChunkData : Packet { + void ToStream(StreamOutput *stream) override { + stream->WriteInt(ChunkX); + stream->WriteInt(ChunkZ); + stream->WriteBool(GroundUpContinuous); + stream->WriteInt(PrimaryBitMask); + stream->WriteVarInt(Data.size()); + stream->WriteByteArray(Data); + stream->WriteVarInt(BlockEntities.size()); + LOG(FATAL) << "Serializing unimplemented packet"; + } + + void FromStream(StreamInput *stream) override { + ChunkX = stream->ReadInt(); + ChunkZ = stream->ReadInt(); + GroundUpContinuous = stream->ReadBool(); + PrimaryBitMask = stream->ReadVarInt(); + int Size = stream->ReadVarInt(); + Data = stream->ReadByteArray(Size); + int NumberOfBlockEntities = stream->ReadVarInt(); //TODO: Need NBT + for (int i = 0; i < NumberOfBlockEntities; i++) { + //BlockEntities[i] = stream->ReadNbt(); + } + } + + int GetPacketId() override { + return PacketNamePlayCB::ChunkData; + } + + int ChunkX; + int ChunkZ; + bool GroundUpContinuous; + int PrimaryBitMask; + //int Size; + std::vector Data; + //int NumberOfBlockEntities; + std::vector BlockEntities; //TODO: Replace int with NbtTag and implement NbtTree +}; + +struct PacketPlayerPosition : Packet { + void ToStream(StreamOutput *stream) override { + stream->WriteDouble(X); + stream->WriteDouble(FeetY); + stream->WriteDouble(Z); + stream->WriteBool(OnGround); + } + + void FromStream(StreamInput *stream) override { + X = stream->ReadDouble(); + FeetY = stream->ReadDouble(); + Z = stream->ReadDouble(); + OnGround = stream->ReadBool(); + } + + int GetPacketId() override { + return PacketNamePlaySB::PlayerPosition; + } + + double X; + double FeetY; + double Z; + bool OnGround; + + PacketPlayerPosition(double X, double Y, double Z, bool ground) : X(X), FeetY(Y), Z(Z), OnGround(ground) {} +}; + +struct PacketPlayerLook : Packet { + void ToStream(StreamOutput *stream) override { + stream->WriteFloat(Yaw); + stream->WriteFloat(Pitch); + stream->WriteBool(OnGround); + } + + void FromStream(StreamInput *stream) override { + Yaw = stream->ReadFloat(); + Pitch = stream->ReadFloat(); + OnGround = stream->ReadBool(); + } + + int GetPacketId() override { + return PacketNamePlaySB::PlayerLook; + } + + float Yaw; + float Pitch; + bool OnGround; + + PacketPlayerLook(float Yaw, float Pitch, bool ground) : Yaw(Yaw), Pitch(Pitch), OnGround(ground) {} +}; + +struct PacketUpdateHealth : Packet { + void ToStream(StreamOutput *stream) override { + stream->WriteFloat(Health); + stream->WriteVarInt(Food); + stream->WriteFloat(FoodSaturation); + } + + void FromStream(StreamInput *stream) override { + Health = stream->ReadFloat(); + Food = stream->ReadVarInt(); + FoodSaturation = stream->ReadFloat(); + } + + int GetPacketId() override { + return PacketNamePlayCB::UpdateHealth; + } + + float Health; + int Food; + float FoodSaturation; +}; \ No newline at end of file diff --git a/include/network/Socket.hpp b/include/network/Socket.hpp new file mode 100644 index 0000000..48bcad9 --- /dev/null +++ b/include/network/Socket.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include + +#include + +/** + * Platform independent class for working with platform dependent hardware socket + * @brief Wrapper around raw sockets + * @warning Connection state is based on lifetime of Socket object instance, ie connected at ctor and disconnect at dtor + * @todo Replace SFML's socket with WinSock and POSIX's socket implementation + */ +class Socket { + sf::TcpSocket socket; +public: + /** + * Constructs Socket class instance from IP's string and Port number and connects to remote server + * @param[in] address IP address of remote server. String should be ANSI and contains 4 one-byte values separated by dots + * @param[in] port target port of remote server to connect + * @throw std::runtime_error if connection is failed + */ + Socket(std::string address, unsigned short port); + + /** + * Destruct Socket instance and disconnect from server + * @warning There is no way to force disconnect, except use delete for manually allocated objects and scope of visibility for variables on stack + */ + ~Socket(); + + /** + * Reads data from socket and write to buffer + * @warning This is blocking function, and execution flow will not be returned until all required data is sended + * @warning Reported buffer length must be <= actual size of buffer, or memory corruption will be caused + * @param[out] buffPtr Pointer to buffer, where data must be placed + * @param[in] buffLen Length of data, that must be readed from server and writed to buffer + */ + void Read(unsigned char *buffPtr, size_t buffLen); + + /** + * Writes data from buffer to socket + * @warning This is blocking function, and execution flow will not be returned until all required data is received + * @param[in] buffPtr Pointer to buffer that contain data to send + * @param[in] buffLen Length of buffer + */ + void Write(unsigned char *buffPtr, size_t buffLen); +}; \ No newline at end of file diff --git a/include/network/Stream.hpp b/include/network/Stream.hpp new file mode 100644 index 0000000..a24dfbe --- /dev/null +++ b/include/network/Stream.hpp @@ -0,0 +1,107 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +class Stream { +public: + virtual ~Stream() {}; +}; + +class StreamInput : Stream { + virtual void ReadData(unsigned char *buffPtr, size_t buffLen) = 0; +public: + virtual ~StreamInput() = default; + bool ReadBool(); + signed char ReadByte(); + unsigned char ReadUByte(); + short ReadShort(); + unsigned short ReadUShort(); + int ReadInt(); + long long ReadLong(); + float ReadFloat(); + double ReadDouble(); + std::string ReadString(); + std::string ReadChat(); + int ReadVarInt(); + long long ReadVarLong(); + std::vector ReadEntityMetadata(); + std::vector ReadSlot(); + std::vector ReadNbtTag(); + Vector ReadPosition(); + unsigned char ReadAngle(); + std::vector ReadUuid(); + std::vector ReadByteArray(size_t arrLength); +}; + +class StreamOutput : Stream { + virtual void WriteData(unsigned char *buffPtr, size_t buffLen) = 0; +public: + virtual ~StreamOutput() = default; + void WriteBool(bool value); + void WriteByte(signed char value); + void WriteUByte(unsigned char value); + void WriteShort(short value); + void WriteUShort(unsigned short value); + void WriteInt(int value); + void WriteLong(long long value); + void WriteFloat(float value); + void WriteDouble(double value); + void WriteString(std::string value); + void WriteChat(std::string value); + void WriteVarInt(int value); + void WriteVarLong(long long value); + void WriteEntityMetadata(std::vector value); + void WriteSlot(std::vector value); + void WriteNbtTag(std::vector value); + void WritePosition(Vector value); + void WriteAngle(unsigned char value); + void WriteUuid(std::vector value); + void WriteByteArray(std::vector value); +}; + +class StreamBuffer : public StreamInput, public StreamOutput { + unsigned char *buffer; + unsigned char *bufferPtr; + size_t bufferLength; + + void ReadData(unsigned char *buffPtr, size_t buffLen) override; + void WriteData(unsigned char *buffPtr, size_t buffLen) override; + +public: + StreamBuffer(unsigned char *data, size_t dataLen); + StreamBuffer(size_t bufferLen); + ~StreamBuffer(); + + std::vector GetBuffer(); +}; + +class StreamCounter : public StreamOutput { + void WriteData(unsigned char *buffPtr, size_t buffLen) override; + + size_t size; +public: + StreamCounter(size_t initialSize = 0); + ~StreamCounter(); + + size_t GetCountedSize(); +}; + +class StreamSocket : public StreamInput, public StreamOutput { + Socket *socket; + void ReadData(unsigned char *buffPtr, size_t buffLen) override; + void WriteData(unsigned char *buffPtr, size_t buffLen) override; +public: + StreamSocket(Socket *socketPtr); + ~StreamSocket() = default; +}; \ No newline at end of file diff --git a/include/world/Block.hpp b/include/world/Block.hpp new file mode 100644 index 0000000..2f823fe --- /dev/null +++ b/include/world/Block.hpp @@ -0,0 +1,15 @@ +#pragma once + +struct Block { + Block(); + + Block(unsigned short id, unsigned char state); + + ~Block(); + + unsigned short id : 13; + unsigned char state : 4; + //unsigned char light:4; +}; + +bool operator<(const Block &lhs, const Block &rhs); \ No newline at end of file diff --git a/include/world/Collision.hpp b/include/world/Collision.hpp new file mode 100644 index 0000000..b88fbf7 --- /dev/null +++ b/include/world/Collision.hpp @@ -0,0 +1,8 @@ +#pragma once + +struct AABB { + double x,y,z; + double w,l,h; +}; + +bool TestCollision(AABB first, AABB second); \ No newline at end of file diff --git a/include/world/Section.hpp b/include/world/Section.hpp new file mode 100644 index 0000000..139b5b5 --- /dev/null +++ b/include/world/Section.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include +#include +#include + +#include + +#include +#include +#include + +const int SECTION_WIDTH = 16; +const int SECTION_LENGTH = 16; +const int SECTION_HEIGHT = 16; + +class Section { + std::vector m_palette; + byte *m_dataBlocks = nullptr; + size_t m_dataBlocksLen; + byte *m_dataLight = nullptr; + byte *m_dataSkyLight = nullptr; + byte m_bitsPerBlock = 0; + std::vector m_blocks; + std::condition_variable parseWaiter; + + Section(); + + Vector worldPosition; + +public: + void Parse(); + + Section(Vector position, byte *dataBlocks, size_t dataBlocksLength, byte *dataLight, byte *dataSky, byte bitsPerBlock, + std::vector palette); + + ~Section(); + + Block &GetBlock(Vector pos); + + Section &operator=(Section other); + + friend void swap(Section &a, Section &b); + + Section(const Section &other); + + Vector GetPosition(); +}; \ No newline at end of file diff --git a/include/world/World.hpp b/include/world/World.hpp new file mode 100644 index 0000000..6e5eedb --- /dev/null +++ b/include/world/World.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +#include + +#include +#include +#include +#include + +class World { + //utility vars + World(const World &other); + + World &operator=(const World &other); + + //game vars + int dimension = 0; + + //game methods + Section ParseSection(StreamInput *data, Vector position); + +public: + World(); + + ~World(); + + void ParseChunkData(std::shared_ptr packet); + + std::map sections; + + bool isPlayerCollides(double X, double Y, double Z); +}; \ No newline at end of file diff --git a/src/core/AssetManager.cpp b/src/core/AssetManager.cpp index 4fb5388..f4c0801 100644 --- a/src/core/AssetManager.cpp +++ b/src/core/AssetManager.cpp @@ -1,5 +1,4 @@ - -#include "AssetManager.hpp" +#include namespace fs = std::experimental::filesystem; diff --git a/src/core/AssetManager.hpp b/src/core/AssetManager.hpp deleted file mode 100644 index ebb339f..0000000 --- a/src/core/AssetManager.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include "../world/Block.hpp" -#include "../graphics/Texture.hpp" - -struct TextureCoordinates { - TextureCoordinates(float x = -1, float y = -1, float w = -1, float h = -1) : x(x), y(y), w(w), h(h) {} - - bool operator==(const TextureCoordinates &rhs) const { - return x == rhs.x && - y == rhs.y && - w == rhs.w && - h == rhs.h; - } - - explicit operator bool() const { - return !(*this == TextureCoordinates(-1, -1, -1, -1)); - } - - float x, y, w, h; -}; - -struct BlockTextureId { - //Block sides: 0 - bottom, 1 - top, 2 - north, 3 - south, 4 - west, 5 - east 6 - every side - BlockTextureId(int id = 0, int state = 0, int side = 6) : id(id), state(state), side(side) {} - - int id:9; - int state:4; - int side:3; - - - - bool operator<(const BlockTextureId &rhs) const { - if (id < rhs.id) - return true; - if (rhs.id < id) - return false; - if (state < rhs.state) - return true; - if (rhs.state < state) - return false; - return side < rhs.side; - } -}; - -class AssetManager { - Texture *textureAtlas; - std::map assetIds; - std::map assetTextures; -public: - AssetManager(); - - ~AssetManager(); - - void LoadTextureResources(); - - TextureCoordinates GetTextureByAssetName(std::string AssetName); - - std::string GetTextureAssetNameByBlockId(BlockTextureId block); - - GLuint GetTextureAtlas(); - - void LoadIds(); - - TextureCoordinates GetTextureByBlock(BlockTextureId block); -}; diff --git a/src/core/Core.cpp b/src/core/Core.cpp index 50bcd81..5538439 100644 --- a/src/core/Core.cpp +++ b/src/core/Core.cpp @@ -1,139 +1,5 @@ #include "Core.hpp" -GLenum glCheckError_(const char *file, int line) { - GLenum errorCode; - while ((errorCode = glGetError()) != GL_NO_ERROR) { - std::string error; - switch (errorCode) { - case GL_INVALID_ENUM: - error = "INVALID_ENUM"; - break; - case GL_INVALID_VALUE: - error = "INVALID_VALUE"; - break; - case GL_INVALID_OPERATION: - error = "INVALID_OPERATION"; - break; - case GL_STACK_OVERFLOW: - error = "STACK_OVERFLOW"; - break; - case GL_STACK_UNDERFLOW: - error = "STACK_UNDERFLOW"; - break; - case GL_OUT_OF_MEMORY: - error = "OUT_OF_MEMORY"; - break; - case GL_INVALID_FRAMEBUFFER_OPERATION: - error = "INVALID_FRAMEBUFFER_OPERATION"; - break; - } - LOG(ERROR) << "OpenGL error: " << error << " at " << file << ":" << line; - } - return errorCode; -} - -#define glCheckError() glCheckError_(__FILE__, __LINE__) - -const GLfloat vertices[] = { - //Z+ edge - -0.5f, 0.5f, 0.5f, - -0.5f, -0.5f, 0.5f, - 0.5f, -0.5f, 0.5f, - -0.5f, 0.5f, 0.5f, - 0.5f, -0.5f, 0.5f, - 0.5f, 0.5f, 0.5f, - - //Z- edge - -0.5f, -0.5f, -0.5f, - -0.5f, 0.5f, -0.5f, - 0.5f, -0.5f, -0.5f, - 0.5f, -0.5f, -0.5f, - -0.5f, 0.5f, -0.5f, - 0.5f, 0.5f, -0.5f, - - //X+ edge - -0.5f, -0.5f, -0.5f, - -0.5f, -0.5f, 0.5f, - -0.5f, 0.5f, -0.5f, - -0.5f, 0.5f, -0.5f, - -0.5f, -0.5f, 0.5f, - -0.5f, 0.5f, 0.5f, - - //X- edge - 0.5f, -0.5f, 0.5f, - 0.5f, 0.5f, -0.5f, - 0.5f, 0.5f, 0.5f, - 0.5f, -0.5f, 0.5f, - 0.5f, -0.5f, -0.5f, - 0.5f, 0.5f, -0.5f, - - //Y+ edge - 0.5f, 0.5f, -0.5f, - -0.5f, 0.5f, 0.5f, - 0.5f, 0.5f, 0.5f, - 0.5f, 0.5f, -0.5f, - -0.5f, 0.5f, -0.5f, - -0.5f, 0.5f, 0.5f, - - //Y- edge - -0.5f, -0.5f, 0.5f, - 0.5f, -0.5f, -0.5f, - 0.5f, -0.5f, 0.5f, - -0.5f, -0.5f, -0.5f, - 0.5f, -0.5f, -0.5f, - -0.5f, -0.5f, 0.5f, -}; - -const GLfloat uv_coords[] = { - //Z+ - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, - - //Z- - 1.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 0.0f, - 0.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - - //X+ - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, - - //X- - 0.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, - - //Y+ - 0.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, - - //Y- - 1.0f, 0.0f, - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, -}; - Core::Core() { LOG(INFO) << "Core initializing..."; InitSfml(900, 450, "AltCraft"); @@ -145,7 +11,7 @@ Core::Core() { std::thread loop = std::thread(&Core::UpdateGameState, this); std::swap(loop, gameStateLoopThread); assetManager = new AssetManager; - PrepareToWorldRendering(); + PrepareToRendering(); LOG(INFO) << "Core is initialized"; glCheckError(); } @@ -254,8 +120,8 @@ void Core::InitGlew() { //glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace(GL_CCW); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + //glEnable(GL_BLEND); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glCheckError(); } @@ -336,10 +202,6 @@ void Core::HandleMouseCapture() { //camera.ProcessMouseMovement(mouseXDelta, mouseYDelta); } -void Core::RenderGui(Gui &Target) { - Target.WHY++; -} - void Core::RenderWorld() { shader->Use(); glCheckError(); @@ -356,9 +218,8 @@ void Core::RenderWorld() { glCheckError(); - glBindVertexArray(VAO); - for (auto §ionPos : toRender) { - //Section §ion = gameState->world.sections.find(sectionPos)->second; + for (auto &render : toRender) { + Section §ion = *availableChunks.find(render)->second.GetSection(); std::vector sectionCorners = { Vector(0, 0, 0), @@ -373,8 +234,9 @@ void Core::RenderWorld() { bool isBreak = true; for (auto &it:sectionCorners) { glm::mat4 vp = projection * view; - glm::vec3 point(sectionPos.GetX() * 16 + it.GetX(), sectionPos.GetY() * 16 + it.GetY(), - sectionPos.GetZ() * 16 + it.GetZ()); + glm::vec3 point(section.GetPosition().GetX() * 16 + it.GetX(), + section.GetPosition().GetY() * 16 + it.GetY(), + section.GetPosition().GetZ() * 16 + it.GetZ()); glm::vec4 p = vp * glm::vec4(point, 1); glm::vec3 res = glm::vec3(p) / p.w; if (res.x < 1 && res.x > -1 && res.y < 1 && res.y > -1 && res.z > 0) { @@ -383,24 +245,13 @@ void Core::RenderWorld() { } } if (isBreak && glm::length(gameState->Position() - - glm::vec3(sectionPos.GetX() * 16, sectionPos.GetY() * 16, sectionPos.GetZ() * 16)) > - 30) { + glm::vec3(section.GetPosition().GetX() * 16, + section.GetPosition().GetY() * 16, + section.GetPosition().GetZ() * 16)) > 30.0f) { continue; } - - std::vector &arrOfModels = toRenderModels[sectionPos]; - std::vector &arrOfBlocks = toRenderBlocks[sectionPos]; - - glBindBuffer(GL_ARRAY_BUFFER, VBO3); - glBufferData(GL_ARRAY_BUFFER, arrOfModels.size() * sizeof(glm::mat4), arrOfModels.data(), GL_DYNAMIC_DRAW); - - glBindBuffer(GL_ARRAY_BUFFER, VBO4); - glBufferData(GL_ARRAY_BUFFER, arrOfBlocks.size() * sizeof(glm::vec2), arrOfBlocks.data(), GL_DYNAMIC_DRAW); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glDrawArraysInstanced(GL_TRIANGLES, 0, 36, arrOfModels.size()); + availableChunks.find(render)->second.Render(renderState); } - glBindVertexArray(0); glCheckError(); } @@ -411,66 +262,10 @@ void Core::SetMouseCapture(bool IsCaptured) { window->setMouseCursorVisible(!IsCaptured); } -void Core::PrepareToWorldRendering() { - //Cube-rendering data - glGenBuffers(1, &VBO); - glGenBuffers(1, &VBO2); - glGenBuffers(1, &VBO3); - glGenBuffers(1, &VBO4); - glGenVertexArrays(1, &VAO); - - glBindVertexArray(VAO); - { - //Cube vertices - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0); - glEnableVertexAttribArray(0); - - //Cube UVs - glBindBuffer(GL_ARRAY_BUFFER, VBO2); - glBufferData(GL_ARRAY_BUFFER, sizeof(uv_coords), uv_coords, GL_STATIC_DRAW); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0); - glEnableVertexAttribArray(2); - - //Blocks ids - glBindBuffer(GL_ARRAY_BUFFER, VBO4); - glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * 16 * 16 * 16, NULL, GL_DYNAMIC_DRAW); - glVertexAttribPointer(7, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0); - glEnableVertexAttribArray(7); - glVertexAttribDivisor(7, 1); - glCheckError(); - - //Blocks models - glBindBuffer(GL_ARRAY_BUFFER, VBO3); - glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * 16 * 16 * 16, NULL, GL_DYNAMIC_DRAW); - glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat), 0); - glEnableVertexAttribArray(8); - glVertexAttribPointer(8 + 1, 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat), - (void *) (1 * 4 * sizeof(GLfloat))); - glEnableVertexAttribArray(8 + 1); - glVertexAttribPointer(8 + 2, 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat), - (void *) (2 * 4 * sizeof(GLfloat))); - glEnableVertexAttribArray(8 + 2); - glVertexAttribPointer(8 + 3, 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat), - (void *) (3 * 4 * sizeof(GLfloat))); - glEnableVertexAttribArray(8 + 3); - glVertexAttribDivisor(8, 1); - glVertexAttribDivisor(8 + 1, 1); - glVertexAttribDivisor(8 + 2, 1); - glVertexAttribDivisor(8 + 3, 1); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - } - glBindVertexArray(0); - - glCheckError(); - +void Core::PrepareToRendering() { shader = new Shader("./shaders/block.vs", "./shaders/block.fs"); shader->Use(); - shader2 = new Shader("./shaders/simple.vs", "./shaders/simple.fs"); - LOG(INFO) << "Initializing texture atlas..."; //TextureAtlas texture glActiveTexture(GL_TEXTURE0); @@ -507,10 +302,10 @@ void Core::PrepareToWorldRendering() { GLuint bp1 = 0; GLuint ubo = glGetUniformBlockIndex(shader->Program, "TextureIndexes"); glUniformBlockBinding(shader->Program, ubo, bp1); - glGenBuffers(1, &UBO); - glBindBuffer(GL_UNIFORM_BUFFER, UBO); - glBindBufferBase(GL_UNIFORM_BUFFER, bp1, UBO); - glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::vec4) + sizeof(glm::vec4) * 1023, NULL, GL_STATIC_DRAW); + glGenBuffers(1, &UboTextureIndexes); + glBindBuffer(GL_UNIFORM_BUFFER, UboTextureIndexes); + glBindBufferBase(GL_UNIFORM_BUFFER, bp1, UboTextureIndexes); + glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::vec4) + sizeof(glm::vec4) * 1023, nullptr, GL_STATIC_DRAW); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(GLint), &totalTextures); //copy totalTextures for (size_t i = 0; i < indexes.size(); i++) { size_t baseOffset = sizeof(glm::vec4); @@ -523,26 +318,13 @@ void Core::PrepareToWorldRendering() { GLuint bp2 = 1; GLuint ubo2_index = glGetUniformBlockIndex(shader->Program, "TextureData"); glUniformBlockBinding(shader->Program, ubo2_index, bp2); - glGenBuffers(1, &UBO2); - glBindBuffer(GL_UNIFORM_BUFFER, UBO2); - glBindBufferBase(GL_UNIFORM_BUFFER, bp2, UBO2); - glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::vec4) * 1024, NULL, GL_STATIC_DRAW); + glGenBuffers(1, &UboTextureData); + glBindBuffer(GL_UNIFORM_BUFFER, UboTextureData); + glBindBufferBase(GL_UNIFORM_BUFFER, bp2, UboTextureData); + glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::vec4) * 1024, nullptr, GL_STATIC_DRAW); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::vec4) * textureCoordinates.size(), textureCoordinates.data()); glBindBuffer(GL_UNIFORM_BUFFER, 0); glCheckError(); - - //Draw Lines preparing - glGenBuffers(1, &VBO5); - glGenVertexArrays(1, &VAO2); - glBindVertexArray(VAO2); - { - glBindBuffer(GL_ARRAY_BUFFER, VBO5); - glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(GLfloat), NULL, GL_DYNAMIC_DRAW); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0); - glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } - glBindVertexArray(0); } void Core::UpdateChunksToRender() { @@ -564,51 +346,16 @@ void Core::UpdateChunksToRender() { continue; toRender.push_back(it.first); } - if (firstTime) - LOG(INFO) << "Chunks to render: " << toRender.size(); for (auto &it:toRender) { - Section §ion = gameState->world.sections.find(it)->second; - std::vector models; - std::vector blocks; - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - Block block = section.GetBlock(Vector(x, y, z)); - if (block.id == 0) - continue; - unsigned char isVisible = 0; - if (x == 0 || x == 15 || y == 0 || y == 15 || z == 0 || z == 15) { - isVisible = 0; - } else { - isVisible |= (section.GetBlock(Vector(x + 1, y, z)).id != 0) << 0; - isVisible |= (section.GetBlock(Vector(x - 1, y, z)).id != 0) << 1; - isVisible |= (section.GetBlock(Vector(x, y + 1, z)).id != 0) << 2; - isVisible |= (section.GetBlock(Vector(x, y - 1, z)).id != 0) << 3; - isVisible |= (section.GetBlock(Vector(x, y, z + 1)).id != 0) << 4; - isVisible |= (section.GetBlock(Vector(x, y, z - 1)).id != 0) << 5; - } - if (isVisible == 0x3F) - continue; - glm::vec2 data(block.id, block.state); - blocks.push_back(data); - glm::mat4 model; - model = glm::translate(model, glm::vec3(it.GetX() * 16, it.GetY() * 16, it.GetZ() * 16)); - model = glm::translate(model, glm::vec3(x, y, z)); - double size = 0.999; - model = glm::scale(model, glm::vec3(size, size, size)); - models.push_back(model); - } - } + if (availableChunks.find(it) == availableChunks.end()) { + auto pair = std::make_pair(it, RenderSection(&gameState->world, it)); + availableChunks.insert(pair); + } else { + availableChunks.find(it)->second.UpdateState(); } - toRenderBlocks[it] = blocks; - toRenderModels[it] = models; } - std::sort(toRender.begin(), toRender.end(), [this](const Vector &lhs, const Vector &rhs) { - return glm::length((glm::vec3) lhs - gameState->Position()) < - glm::length((glm::vec3) rhs - gameState->Position()); - }); if (firstTime) - LOG(INFO) << "Chunks is prepared to rendering..."; + LOG(INFO) << "Chunks to render: " << toRender.size() << " of " << availableChunks.size(); firstTime = false; } diff --git a/src/core/Core.hpp b/src/core/Core.hpp deleted file mode 100644 index 4cc334c..0000000 --- a/src/core/Core.hpp +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include "../gamestate/GameState.hpp" -#include "../network/NetworkClient.hpp" -#include "../gui/Gui.hpp" -#include "../graphics/Shader.hpp" -#include "AssetManager.hpp" - -class Core { - GameState *gameState; - NetworkClient *client; - sf::Window *window; - AssetManager *assetManager; - bool isMouseCaptured = false; - bool isRunning = true; - enum { - MainMenu, - Loading, - Playing, - PauseMenu, - } currentState = Playing; - float mouseXDelta, mouseYDelta; - float deltaTime; - float absTime; - - void RenderWorld(); - - void RenderGui(Gui &Target); - - void HandleMouseCapture(); - - void HandleEvents(); - - void InitSfml(unsigned int WinWidth, unsigned int WinHeight, std::string WinTitle); - - void InitGlew(); - - void SetMouseCapture(bool IsCaptured); - - void PrepareToWorldRendering(); - - void RenderFrame(); - - unsigned int width(); - - unsigned int height(); - - void UpdateChunksToRender(); - - void UpdateGameState(); - - std::thread gameStateLoopThread; - - Shader *shader,*shader2; - //Cube verticies, Cube VAO, Cube UVs, TextureIndexes UBO, TextureData UBO, TextureData2 UBO, Blocks VBO, Models VBO, Line VAO, Lines VBO - GLuint VBO, VAO, VBO2, UBO, UBO2, VBO3, VBO4, VAO2, VBO5; - std::vector toRender; - std::vector optimizedRender; - - int ChunkDistance = 2; - - std::map> toRenderModels; - std::map> toRenderBlocks; - //std::map, std::vector > > sectionsRenderingData; - - double tickRate=0; - -public: - Core(); - - ~Core(); - - void Exec(); -}; diff --git a/src/gamestate/GameState.cpp b/src/gamestate/GameState.cpp deleted file mode 100644 index 316d5f1..0000000 --- a/src/gamestate/GameState.cpp +++ /dev/null @@ -1,389 +0,0 @@ -#include "GameState.hpp" - -GameState::GameState(NetworkClient *Net, bool &quit) : nc(Net), isRunning(quit) { - Front = glm::vec3(0.0f, 0.0f, -1.0f); - this->SetPosition(glm::vec3(0.0f, 0.0f, 3.0f)); - this->WorldUp = glm::vec3(0.0f, 1.0f, 0.0f); - this->updateCameraVectors(); -} - -void GameState::Update(float deltaTime) { - if (g_IsGameStarted) { - std::chrono::steady_clock clock; - static auto timeOfPreviousSendedPacket(clock.now()); - auto delta = clock.now() - timeOfPreviousSendedPacket; - using namespace std::chrono_literals; - if (delta >= 50ms) { - nc->SendPacket(std::make_shared(g_PlayerX, g_PlayerY, g_PlayerZ, g_PlayerYaw, - g_PlayerPitch, g_OnGround)); - timeOfPreviousSendedPacket = clock.now(); - } - - const float gravity = -9.8f; - g_PlayerVelocityY += gravity * deltaTime; - - bool isCollides = world.isPlayerCollides(g_PlayerX, g_PlayerY + g_PlayerVelocityY * deltaTime, - g_PlayerZ); - if (!isCollides) { - g_PlayerY += g_PlayerVelocityY * deltaTime; - g_OnGround = false; - } else { - g_PlayerVelocityY = 0; - if (g_OnGround == false) { - auto updatePacket = std::make_shared(g_PlayerX, g_PlayerY, g_PlayerZ, true); - nc->SendPacket(updatePacket); - } - g_OnGround = true; - } - - isCollides = world.isPlayerCollides(g_PlayerX + g_PlayerVelocityX * deltaTime, g_PlayerY, - g_PlayerZ + g_PlayerVelocityZ * deltaTime); - if (!isCollides) { - g_PlayerX += g_PlayerVelocityX * deltaTime; - g_PlayerZ += g_PlayerVelocityZ * deltaTime; - } - - const float AirResistance = 10.0f; - glm::vec3 vel(g_PlayerVelocityX, 0, g_PlayerVelocityZ); - glm::vec3 resistForce = -vel * AirResistance * deltaTime; - vel += resistForce; - g_PlayerVelocityX = vel.x; - g_PlayerVelocityZ = vel.z; - } - - - //Packet handling - auto ptr = nc->ReceivePacket(); - while (ptr != nullptr) { - switch ((PacketNamePlayCB) ptr->GetPacketId()) { - case SpawnObject: - break; - case SpawnExperienceOrb: - break; - case SpawnGlobalEntity: - break; - case SpawnMob: - break; - case SpawnPainting: - break; - case SpawnPlayer: - break; - case AnimationCB: - break; - case Statistics: - break; - case BlockBreakAnimation: - break; - case UpdateBlockEntity: - break; - case BlockAction: - break; - case BlockChange: - break; - case BossBar: - break; - case ServerDifficulty: - break; - case TabCompleteCB: - break; - case ChatMessageCB: - break; - case MultiBlockChange: - break; - case ConfirmTransactionCB: - break; - case CloseWindowCB: - break; - case OpenWindow: - break; - case WindowItems: - break; - case WindowProperty: - break; - case SetSlot: - break; - case SetCooldown: - break; - case PluginMessageCB: - break; - case NamedSoundEffect: - break; - case DisconnectPlay: { - auto packet = std::static_pointer_cast(ptr); - LOG(INFO) << "Disconnect reason: " << packet->Reason; - isRunning = false; - break; - } - case EntityStatus: - break; - case Explosion: - break; - case UnloadChunk: - break; - case ChangeGameState: - break; - case KeepAliveCB: - LOG(WARNING) << "Receive KeepAlive packet in GameState handler"; - break; - case ChunkData: { - auto packet = std::static_pointer_cast(ptr); - world.ParseChunkData(packet); - break; - } - case Effect: - break; - case Particle: - break; - case JoinGame: { - auto packet = std::static_pointer_cast(ptr); - g_PlayerEid = packet->EntityId; - g_Gamemode = (packet->Gamemode & 0b11111011); - g_Dimension = packet->Dimension; - g_Difficulty = packet->Difficulty; - g_MaxPlayers = packet->MaxPlayers; - g_LevelType = packet->LevelType; - g_ReducedDebugInfo = packet->ReducedDebugInfo; - LOG(INFO) << "Gamemode is " << g_Gamemode << ", Difficulty is " << (int) g_Difficulty - << ", Level Type is " << g_LevelType; - break; - } - case Map: - break; - case EntityRelativeMove: - break; - case EntityLookAndRelativeMove: - break; - case EntityLook: - break; - case Entity: - break; - case VehicleMove: - break; - case OpenSignEditor: - break; - case PlayerAbilitiesCB: - break; - case CombatEvent: - break; - case PlayerListItem: - break; - case PlayerPositionAndLookCB: { - auto packet = std::static_pointer_cast(ptr); - if ((packet->Flags & 0x10) != 0) { - g_PlayerPitch += packet->Pitch; - } else { - g_PlayerPitch = packet->Pitch; - }; - - if ((packet->Flags & 0x08) != 0) { - g_PlayerYaw += packet->Yaw; - } else { - g_PlayerYaw = packet->Yaw; - } - - if ((packet->Flags & 0x01) != 0) { - g_PlayerX += packet->X; - } else { - g_PlayerX = packet->X; - } - - if ((packet->Flags & 0x02) != 0) { - g_PlayerY += packet->Y; - } else { - g_PlayerY = packet->Y; - } - - if ((packet->Flags & 0x04) != 0) { - g_PlayerZ += packet->Z; - } else { - g_PlayerZ = packet->Z; - } - - //if (!g_IsGameStarted) - LOG(INFO) << "PlayerPos is " << g_PlayerX << ", " << g_PlayerY << ", " << g_PlayerZ << "\t\tAngle: " - << g_PlayerYaw << "," << g_PlayerPitch; - - g_IsGameStarted = true; - - auto packetResponse = std::make_shared(packet->TeleportId); - auto packetPerformRespawn = std::make_shared(0); - - nc->SendPacket(packetResponse); - nc->SendPacket(packetPerformRespawn); - break; - } - case UseBed: - break; - case UnlockRecipes: - break; - case DestroyEntities: - break; - case RemoveEntityEffect: - break; - case ResourcePackSend: - break; - case Respawn: - break; - case EntityHeadLook: - break; - case SelectAdvancementTab: - break; - case WorldBorder: - break; - case Camera: - break; - case HeldItemChangeCB: - break; - case DisplayScoreboard: - break; - case EntityMetadata: - break; - case AttachEntity: - break; - case EntityVelocity: - break; - case EntityEquipment: - break; - case SetExperience: - break; - case UpdateHealth: { - auto packet = std::static_pointer_cast(ptr); - g_PlayerHealth = packet->Health; - if (g_PlayerHealth <= 0) { - LOG(INFO) << "Player is dead. Respawning..."; - auto packetPerformRespawn = std::make_shared(0); - nc->SendPacket(packetPerformRespawn); - } - break; - } - case ScoreboardObjective: - break; - case SetPassengers: - break; - case Teams: - break; - case UpdateScore: - break; - case SpawnPosition: { - auto packet = std::static_pointer_cast(ptr); - g_SpawnPosition = packet->Location; - LOG(INFO) << "Spawn position is " << g_SpawnPosition.GetX() << "," << g_SpawnPosition.GetY() << "," - << g_SpawnPosition.GetZ(); - break; - } - case TimeUpdate: - break; - case Title: - break; - case SoundEffect: - break; - case PlayerListHeaderAndFooter: - break; - case CollectItem: - break; - case EntityTeleport: - break; - case Advancements: - break; - case EntityProperties: - break; - case EntityEffect: - break; - } - ptr = nc->ReceivePacket(); - } -} - -void GameState::HandleMovement(GameState::Direction direction, float deltaTime) { - const float PlayerSpeed = 40.0; - float velocity = PlayerSpeed * deltaTime; - glm::vec3 vel(g_PlayerVelocityX, g_PlayerVelocityY, g_PlayerVelocityZ); - glm::vec3 front(cos(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch())), 0, - sin(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch()))); - front = glm::normalize(front); - glm::vec3 right = glm::normalize(glm::cross(front, this->WorldUp)); - switch (direction) { - case FORWARD: - vel += front * velocity; - break; - case BACKWARD: - vel -= front * velocity; - break; - case RIGHT: - vel += right * velocity; - break; - case LEFT: - vel -= right * velocity; - break; - case JUMP: - if (g_OnGround) { - vel.y += 5; - g_OnGround = false; - } - break; - } - g_PlayerVelocityX = vel.x; - g_PlayerVelocityY = vel.y; - g_PlayerVelocityZ = vel.z; - - /*bool isCollides = world.isPlayerCollides(g_PlayerX, g_PlayerY, g_PlayerZ); - if (isCollides) { - SetPosition(previousPos); - return; - } - auto updatePacket = std::make_shared(g_PlayerX, g_PlayerY, g_PlayerZ, true); - nc->SendPacket(updatePacket);*/ -} - -void GameState::HandleRotation(double yaw, double pitch) { - this->SetYaw(Yaw() + yaw); - this->SetPitch(Pitch() + pitch); - if (this->Pitch() > 89.0f) - this->SetPitch(89.0f); - if (this->Pitch() < -89.0f) - this->SetPitch(-89.0f); - this->updateCameraVectors(); - - auto updatePacket = std::make_shared(g_PlayerYaw, g_PlayerPitch, g_OnGround); - nc->SendPacket(updatePacket); -} - -glm::mat4 GameState::GetViewMatrix() { - return glm::lookAt(this->Position(), this->Position() + this->Front, this->Up); -} - -void GameState::updateCameraVectors() { - glm::vec3 front; - front.x = cos(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch())); - front.y = sin(glm::radians(this->Pitch())); - front.z = sin(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch())); - this->Front = glm::normalize(front); - this->Right = glm::normalize(glm::cross(this->Front, this->WorldUp)); - this->Up = glm::normalize(glm::cross(this->Right, this->Front)); -} - -float GameState::Yaw() { - return g_PlayerYaw + 90; -} - -float GameState::Pitch() { - return -g_PlayerPitch; -} - -void GameState::SetYaw(float yaw) { - g_PlayerYaw = yaw - 90; -} - -void GameState::SetPitch(float pitch) { - g_PlayerPitch = -pitch; -} - -glm::vec3 GameState::Position() { - return glm::vec3(g_PlayerX - 0.5, g_PlayerY + 1.12, g_PlayerZ - 0.5); -} - -void GameState::SetPosition(glm::vec3 Position) { - g_PlayerX = Position.x + 0.5; - g_PlayerY = Position.y - 1.12; - g_PlayerZ = Position.z + 0.5; -} diff --git a/src/gamestate/GameState.hpp b/src/gamestate/GameState.hpp deleted file mode 100644 index 27338fb..0000000 --- a/src/gamestate/GameState.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include -#include -#include -#include "../world/World.hpp" -#include "../network/NetworkClient.hpp" -#include "../utility/Vector.hpp" - -class GameState { - NetworkClient *nc; -public: - GameState(NetworkClient *NetClient, bool &quit); - - void Update(float deltaTime); - - //Navigation - enum Direction { - FORWARD, BACKWARD, LEFT, RIGHT, JUMP - }; - void HandleMovement(GameState::Direction direction, float deltaTime); - void HandleRotation(double yaw, double pitch); - glm::mat4 GetViewMatrix(); - void updateCameraVectors(); - - float Yaw(); - float Pitch(); - void SetYaw(float yaw); - void SetPitch(float pitch); - - glm::vec3 Position(); - void SetPosition(glm::vec3 Position); - glm::vec3 Front; - glm::vec3 Up; - glm::vec3 Right; - glm::vec3 WorldUp; - - //Everything other - World world; - bool &isRunning; - - std::string g_PlayerUuid; - std::string g_PlayerName; - bool g_IsGameStarted; - int g_PlayerEid; - int g_Gamemode; - int g_Dimension; - byte g_Difficulty; - byte g_MaxPlayers; - std::string g_LevelType; - bool g_ReducedDebugInfo; - Vector g_SpawnPosition; - bool g_PlayerInvulnerable; - bool g_PlayerFlying; - bool g_PlayerAllowFlying; - bool g_PlayerCreativeMode; - float g_PlayerFlyingSpeed; - float g_PlayerFovModifier; - float g_PlayerPitch; - float g_PlayerYaw; - double g_PlayerX; - double g_PlayerY; - double g_PlayerZ; - float g_PlayerHealth; - - bool g_OnGround = true; - double g_PlayerVelocityX = 0; - double g_PlayerVelocityY = 0; - double g_PlayerVelocityZ = 0; -}; diff --git a/src/graphics/Gui.cpp b/src/graphics/Gui.cpp new file mode 100644 index 0000000..bbf7cf2 --- /dev/null +++ b/src/graphics/Gui.cpp @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/src/graphics/RenderSection.cpp b/src/graphics/RenderSection.cpp new file mode 100644 index 0000000..fec67b5 --- /dev/null +++ b/src/graphics/RenderSection.cpp @@ -0,0 +1,281 @@ +#include + +const GLfloat vertices[] = { + //Z+ edge + -0.5f, 0.5f, 0.5f, + -0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + + //Z- edge + -0.5f, -0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + 0.5f, 0.5f, -0.5f, + + //X+ edge + -0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + + //X- edge + 0.5f, -0.5f, 0.5f, + 0.5f, 0.5f, -0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, 0.5f, -0.5f, + + //Y+ edge + 0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, 0.5f, + + //Y- edge + -0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, 0.5f, + -0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, +}; + +const GLfloat uv_coords[] = { + //Z+ + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 0.0f, + 1.0f, 1.0f, + + //Z- + 1.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 0.0f, + 0.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 1.0f, + + //X+ + 0.0f, 0.0f, + 1.0f, 0.0f, + 0.0f, 1.0f, + 0.0f, 1.0f, + 1.0f, 0.0f, + 1.0f, 1.0f, + + //X- + 0.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 0.0f, + 1.0f, 1.0f, + + //Y+ + 0.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 0.0f, + 1.0f, 1.0f, + + //Y- + 1.0f, 0.0f, + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 1.0f, + 1.0f, 0.0f, +}; + +void RenderState::SetActiveVao(GLuint Vao) { + if (Vao != ActiveVao) { + glBindVertexArray(Vao); + ActiveVao = Vao; + } +} + +void RenderState::SetActiveShader(GLuint Shader) { + if (Shader != ActiveShader) { + glUseProgram(Shader); + ActiveShader = Shader; + } +} + +const GLuint magicUniqueConstant = 88375; +GLuint RenderSection::VboVertices = magicUniqueConstant; +GLuint RenderSection::VboUvs = magicUniqueConstant; +std::map RenderSection::refCounterVbo; +std::map RenderSection::refCounterVao; + + +RenderSection::RenderSection(World *world, Vector position) : sectionPosition(position), world(world) { + + if (VboVertices == magicUniqueConstant) { + glGenBuffers(1, &VboVertices); + glGenBuffers(1, &VboUvs); + + //Cube vertices + glBindBuffer(GL_ARRAY_BUFFER, VboVertices); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + //Cube UVs + glBindBuffer(GL_ARRAY_BUFFER, VboUvs); + glBufferData(GL_ARRAY_BUFFER, sizeof(uv_coords), uv_coords, GL_STATIC_DRAW); + + LOG(INFO) << "Created VBOs with vertices (" << VboVertices << ") and UVs (" << VboUvs + << ") for ordinary blocks"; + } + + glGenBuffers(1, &VboBlocks); + if (refCounterVbo.find(VboBlocks) == refCounterVbo.end()) + refCounterVbo[VboBlocks] = 0; + refCounterVbo[VboBlocks]++; + + glGenBuffers(1, &VboModels); + if (refCounterVbo.find(VboModels) == refCounterVbo.end()) + refCounterVbo[VboModels] = 0; + refCounterVbo[VboModels]++; + + glGenVertexArrays(1, &Vao); + if (refCounterVao.find(Vao) == refCounterVao.end()) + refCounterVao[Vao] = 0; + refCounterVao[Vao]++; + + glBindVertexArray(Vao); + { + //Cube vertices + glBindBuffer(GL_ARRAY_BUFFER, VboVertices); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr); + glEnableVertexAttribArray(0); + + //Cube UVs + glBindBuffer(GL_ARRAY_BUFFER, VboUvs); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), nullptr); + glEnableVertexAttribArray(2); + + //Blocks ids + glBindBuffer(GL_ARRAY_BUFFER, VboBlocks); + glVertexAttribPointer(7, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), nullptr); + glEnableVertexAttribArray(7); + glVertexAttribDivisor(7, 1); + glCheckError(); + + //Blocks models + size_t sizeOfMat4 = 4 * 4 * sizeof(GLfloat); + glBindBuffer(GL_ARRAY_BUFFER, VboModels); + glVertexAttribPointer(8 + 0, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, nullptr); + glVertexAttribPointer(8 + 1, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *) (1 * 4 * sizeof(GLfloat))); + glVertexAttribPointer(8 + 2, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *) (2 * 4 * sizeof(GLfloat))); + glVertexAttribPointer(8 + 3, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *) (3 * 4 * sizeof(GLfloat))); + glEnableVertexAttribArray(8 + 0); + glEnableVertexAttribArray(8 + 1); + glEnableVertexAttribArray(8 + 2); + glEnableVertexAttribArray(8 + 3); + glVertexAttribDivisor(8 + 0, 1); + glVertexAttribDivisor(8 + 1, 1); + glVertexAttribDivisor(8 + 2, 1); + glVertexAttribDivisor(8 + 3, 1); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + glBindVertexArray(0); + UpdateState(); + glCheckError(); +} + +RenderSection::~RenderSection() { + refCounterVbo[VboBlocks]--; + refCounterVbo[VboModels]--; + refCounterVao[Vao]--; + if (refCounterVbo[VboBlocks] <= 0) + glDeleteBuffers(1, &VboBlocks); + if (refCounterVbo[VboModels] <= 0) + glDeleteBuffers(1, &VboBlocks); + if (refCounterVao[Vao] <= 0) + glDeleteVertexArrays(1, &Vao); +} + +void RenderSection::UpdateState() { + Section *section = &world->sections.find(sectionPosition)->second; + std::vector models; + std::vector blocks; + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + Block block = section->GetBlock(Vector(x, y, z)); + if (block.id == 0) + continue; + + unsigned char isVisible = 0; + if (x == 0 || x == 15 || y == 0 || y == 15 || z == 0 || z == 15) { + isVisible = 0; + } else { + isVisible |= (section->GetBlock(Vector(x + 1, y, z)).id != 0) << 0; + isVisible |= (section->GetBlock(Vector(x - 1, y, z)).id != 0) << 1; + isVisible |= (section->GetBlock(Vector(x, y + 1, z)).id != 0) << 2; + isVisible |= (section->GetBlock(Vector(x, y - 1, z)).id != 0) << 3; + isVisible |= (section->GetBlock(Vector(x, y, z + 1)).id != 0) << 4; + isVisible |= (section->GetBlock(Vector(x, y, z - 1)).id != 0) << 5; + } + if (isVisible == 0x3F) + continue; + + glm::vec2 data(block.id, block.state); + blocks.push_back(data); + glm::mat4 model; + model = glm::translate(model, glm::vec3(section->GetPosition().GetX() * 16, + section->GetPosition().GetY() * 16, + section->GetPosition().GetZ() * 16)); + model = glm::translate(model, glm::vec3(x, y, z)); + double size = 0.999; + model = glm::scale(model, glm::vec3(size, size, size)); + models.push_back(model); + } + } + } + glBindBuffer(GL_ARRAY_BUFFER, VboBlocks); + glBufferData(GL_ARRAY_BUFFER, blocks.size() * sizeof(glm::vec2), blocks.data(), GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, VboModels); + glBufferData(GL_ARRAY_BUFFER, models.size() * sizeof(glm::mat4), models.data(), GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + numOfBlocks = blocks.size(); +} + +void RenderSection::Render(RenderState &state) { + state.SetActiveVao(Vao); + glDrawArraysInstanced(GL_TRIANGLES, 0, 36, numOfBlocks); + glCheckError(); +} + +Section *RenderSection::GetSection() { + return &world->sections.find(sectionPosition)->second; +} + +RenderSection::RenderSection(const RenderSection &other) { + this->world = other.world; + this->VboModels = other.VboModels; + this->VboBlocks = other.VboBlocks; + this->sectionPosition = other.sectionPosition; + this->Vao = other.Vao; + this->numOfBlocks = other.numOfBlocks; + + refCounterVbo[VboBlocks]++; + refCounterVbo[VboModels]++; + refCounterVao[Vao]++; +} diff --git a/src/graphics/Shader.cpp b/src/graphics/Shader.cpp index cf43115..3d2efb8 100644 --- a/src/graphics/Shader.cpp +++ b/src/graphics/Shader.cpp @@ -1,4 +1,4 @@ -#include "Shader.hpp" +#include Shader::Shader(const GLchar *vertexPath, const GLchar *fragmentPath, const GLchar *geometryPath) { vertex = vertexPath; diff --git a/src/graphics/Shader.hpp b/src/graphics/Shader.hpp deleted file mode 100644 index 1bcee3a..0000000 --- a/src/graphics/Shader.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -class Shader -{ -private: - const GLchar *vertex; - const GLchar *fragment; -public: - // Идентификатор программы - GLuint Program; - // Конструктор считывает и собирает шейдер - Shader(const GLchar* vertexPath, const GLchar* fragmentPath, const GLchar* geometryPath = nullptr); - // Использование программы - void Use(); - - void Reload(); -}; \ No newline at end of file diff --git a/src/graphics/Texture.cpp b/src/graphics/Texture.cpp index 5d183c3..e5e2bba 100644 --- a/src/graphics/Texture.cpp +++ b/src/graphics/Texture.cpp @@ -1,4 +1,4 @@ -#include "Texture.hpp" +#include Texture::Texture(std::string filename, GLenum textureWrapping, GLenum textureFiltering) { glGenTextures(1, &texture); diff --git a/src/graphics/Texture.hpp b/src/graphics/Texture.hpp deleted file mode 100644 index 277806a..0000000 --- a/src/graphics/Texture.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include -#include -#include - -class Texture { - Texture(Texture&); - Texture&operator=(Texture&); -public: - GLuint texture; - Texture(std::string filename, GLenum textureWrapping = GL_CLAMP_TO_BORDER, GLenum textureFiltering = GL_NEAREST); - ~Texture(); -}; \ No newline at end of file diff --git a/src/graphics/Widget.cpp b/src/graphics/Widget.cpp new file mode 100644 index 0000000..e53bc87 --- /dev/null +++ b/src/graphics/Widget.cpp @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/src/gui/Gui.cpp b/src/gui/Gui.cpp deleted file mode 100644 index bf600cb..0000000 --- a/src/gui/Gui.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "Gui.hpp" diff --git a/src/gui/Gui.hpp b/src/gui/Gui.hpp deleted file mode 100644 index 641b941..0000000 --- a/src/gui/Gui.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -class Gui { - -public: - int WHY=0; -}; diff --git a/src/gui/Widget.cpp b/src/gui/Widget.cpp deleted file mode 100644 index a88a2bb..0000000 --- a/src/gui/Widget.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "Widget.hpp" diff --git a/src/gui/Widget.hpp b/src/gui/Widget.hpp deleted file mode 100644 index c4d5dc1..0000000 --- a/src/gui/Widget.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -class Widget { - unsigned int x,y,w,h; -public: - Widget(Widget *parent); - ~Widget(); -}; diff --git a/src/main.cpp b/src/main.cpp index 8a7b974..aa30ff8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,4 @@ -#include "core/Core.hpp" +#include "../include/Core.hpp" const char *getTimeSinceProgramStart(void) { static auto initialTime = std::chrono::steady_clock().now(); diff --git a/src/nbt/Nbt.hpp b/src/nbt/Nbt.hpp deleted file mode 100644 index 28e5345..0000000 --- a/src/nbt/Nbt.hpp +++ /dev/null @@ -1,515 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "../utility/utility.h" - -namespace nbt { - enum TagType { - End, //nullptr - Byte, //int8_t - Short, //int16_t - Int, //int32_t - Long, //int64_t - Float, //float - Double, //double - ByteArray, //std::vector - String, //std::string - List, //std::vector - Compound, //std::vector - IntArray, //std::vector - Unknown, //dummy value - }; - - class NbtTag; - - typedef std::vector compound_t; - - typedef std::string string_t; - - typedef std::vector byteArray_t; - - typedef std::vector intArray_t; - - class NbtTag { - TagType type = Unknown; - string_t name = ""; - unsigned char *data = nullptr; - public: - NbtTag(TagType type, string_t name) : type(type), name(name) { - switch (type) { - case End: - data = nullptr; - break; - case Compound: - data = (unsigned char *) new compound_t; - break; - case String: - data = (unsigned char *) new string_t; - break; - case Int: - data = (unsigned char *) new int32_t; - break; - case Long: - data = (unsigned char *) new int64_t; - break; - case Byte: - data = (unsigned char *) new int8_t; - break; - case Short: - data = (unsigned char *) new int16_t; - break; - case Float: - data = (unsigned char *) new float; - break; - case Double: - data = (unsigned char *) new double; - break; - case ByteArray: - data = (unsigned char *) new byteArray_t; - break; - case List: - data = (unsigned char *) new compound_t; - break; - case IntArray: - data = (unsigned char *) new intArray_t; - } - } - - NbtTag(const NbtTag &other) : type(other.type), name(other.name) { - switch (type) { - case Byte: - data = (unsigned char *) new int8_t; - *((int8_t *) data) = *((int8_t *) other.data); - break; - case Short: - data = (unsigned char *) new int16_t; - *((int16_t *) data) = *((int16_t *) other.data); - break; - case Int: - data = (unsigned char *) new int32_t; - *((int32_t *) data) = *((int32_t *) other.data); - break; - case Long: - data = (unsigned char *) new int64_t; - *((int64_t *) data) = *((int64_t *) other.data); - break; - case Float: - data = (unsigned char *) new float; - *((float *) data) = *((float *) other.data); - break; - case Double: - data = (unsigned char *) new double; - *((double *) data) = *((double *) other.data); - break; - case ByteArray: - data = (unsigned char *) new byteArray_t; - *((std::vector *) data) = *((std::vector *) other.data); - break; - case String: - data = (unsigned char *) new string_t; - *((std::string *) data) = *((std::string *) other.data); - break; - case List: - data = (unsigned char *) new compound_t; - *((std::vector *) data) = *((std::vector *) other.data); - break; - case Compound: - data = (unsigned char *) new compound_t; - *((std::vector *) data) = *((std::vector *) other.data); - break; - case IntArray: - data = (unsigned char *) new intArray_t; - *((std::vector *) data) = *((std::vector *) other.data); - break; - } - } - - ~NbtTag() { - switch (type) { - case Byte: - delete ((int8_t *) data); - break; - case Short: - delete ((int16_t *) data); - break; - case Int: - delete ((int32_t *) data); - break; - case Long: - delete ((int64_t *) data); - break; - case Float: - delete ((float *) data); - break; - case Double: - delete ((double *) data); - break; - case ByteArray: - delete ((std::vector *) data); - break; - case String: - delete ((std::string *) data); - break; - case List: - delete ((std::vector *) data); - break; - case Compound: - delete ((std::vector *) data); - break; - case IntArray: - delete ((std::vector *) data); - break; - } - }; - - void swap(NbtTag &other) { - std::swap(other.data, data); - std::swap(other.name, name); - std::swap(other.type, type); - } - - NbtTag &operator=(NbtTag other) { - other.swap(*this); - return *this; - } - - TagType GetType() const{ - return type; - } - - string_t GetName() const{ - return name; - } - - - string_t &GetString() { - string_t &val = *reinterpret_cast(data); - return val; - } - - compound_t &GetCompound() { - std::vector &val = *reinterpret_cast *>(data); - return val; - } - - compound_t &GetList() { - std::vector &val = *reinterpret_cast *>(data); - return val; - } - - int64_t &GetLong() { - int64_t &val = *reinterpret_cast(data); - return val; - } - - float &GetFloat() { - float &val = *reinterpret_cast(data); - return val; - } - - double &GetDouble() { - double &val = *reinterpret_cast(data); - return val; - } - - byteArray_t &GetByteArray() { - auto &val = *reinterpret_cast(data); - return val; - } - - intArray_t &GetIntArray() { - auto &val = *reinterpret_cast(data); - return val; - } - - int16_t &GetShort() { - auto &val = *reinterpret_cast(data); - return val; - } - - int32_t &GetInt() { - auto &val = *reinterpret_cast(data); - return val; - } - - int8_t &GetByte() { - auto &val = *reinterpret_cast(data); - return val; - } - }; - - NbtTag ParseTag(unsigned char *data, size_t &size, TagType listItemType = Unknown) { - size = 0; - TagType type; - if (listItemType == Unknown) { - type = (TagType) *data; - data += 1; - size += 1; - } else - type = listItemType; - string_t name; - if (listItemType == Unknown && type != End) { - short nameLen = *((short *) data); - data += 2; - size += 2; - endswap(&nameLen); - name = std::string((char *) data, nameLen); - data += nameLen; - size += nameLen; - } - NbtTag tag(type, name); - switch (type) { - case Compound: { - do { - size_t s; - tag.GetCompound().push_back(ParseTag(data, s)); - data += s; - size += s; - } while (tag.GetCompound().back().GetType() != End); - tag.GetCompound().pop_back(); - return tag; - } - case String: { - short len = *((short *) data); - data += 2; - size += 2; - endswap(&len); - string_t str((char *) data, len); - data += len; - size += len; - tag.GetString() = str; - return tag; - } - case End: - return tag; - case Long: - tag.GetLong() = *((int64_t *) data); - endswap(&tag.GetLong()); - data += 8; - size += 8; - return tag; - case Short: - tag.GetShort() = *((int16_t *) data); - endswap(&tag.GetShort()); - data += 2; - size += 2; - return tag; - case Float: - tag.GetFloat() = *((float *) data); - endswap(&tag.GetFloat()); - data += 4; - size += 4; - return tag; - case Double: - tag.GetDouble() = *((double *) data); - endswap(&tag.GetDouble()); - data += 8; - size += 8; - return tag; - case Byte: - tag.GetByte() = *((int8_t *) data); - endswap(&tag.GetByte()); - data += 1; - size += 1; - return tag; - case Int: - tag.GetInt() = *((int32_t *) data); - endswap(&tag.GetInt()); - data += 4; - size += 4; - return tag; - case List: { - TagType listType = *((TagType *) data); - data += 1; - size += 1; - int32_t listLength = *((int32_t *) data); - endswap(&listLength); - data += 4; - size += 4; - for (int i = 0; i < listLength; i++) { - size_t s = 0; - std::vector &vec = tag.GetCompound(); - vec.push_back(ParseTag(data, s, listType)); - data += s; - size += s; - } - return tag; - } - case ByteArray: { - int32_t arrLength = *((int32_t *) data); - endswap(&arrLength); - data += 4; - size += 4; - for (int i = 0; i < arrLength; i++) { - signed char val = (signed char) data[i]; - std::vector &vec = tag.GetByteArray(); - vec.push_back(val); - } - data += arrLength; - size += arrLength; - return tag; - } - default: - throw 13; - } - } - - NbtTag ParseTag(unsigned char *data, size_t *optionalSize = nullptr) { - size_t s = 0; - size_t &size = (optionalSize ? *optionalSize : s); - return ParseTag(data, size); - } - - std::vector Decompress(unsigned char *data, size_t dataLen) { - const size_t decompBuffSize = 1024 * 16; - unsigned char *decompBuff = new unsigned char[decompBuffSize]; - std::vector uncompressed; - for (int i = 0; i < decompBuffSize; i++) - decompBuff[i] = 0; - - - z_stream stream; - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - stream.next_in = data; - stream.avail_in = dataLen; - stream.next_out = decompBuff; - stream.avail_out = decompBuffSize; - - if (inflateInit2(&stream, 15 + 32) != Z_OK) { - delete[] decompBuff; - throw 171; - } - - int res; - do { - stream.avail_out = decompBuffSize; - - switch ((res = inflate(&stream, Z_NO_FLUSH))) { - case Z_MEM_ERROR: - throw 172; - case Z_DATA_ERROR: - throw 173; - case Z_NEED_DICT: - throw 174; - } - - uncompressed.resize(uncompressed.size() + decompBuffSize); - std::copy(decompBuff, decompBuff + decompBuffSize, uncompressed.end() - decompBuffSize); - } while (stream.avail_out == 0); - if (res != Z_STREAM_END) - throw 175; - if (inflateEnd(&stream) != Z_OK) - throw 176; - delete[] decompBuff; - return uncompressed; - } - - NbtTag ParseCompressed(unsigned char *data, size_t dataLen) { - auto uncompressed = Decompress(data, dataLen); - NbtTag root = ParseTag(uncompressed.data()); - return root; - } - - NbtTag Parse(unsigned char *data, size_t dataLen) { - bool isCompressed = *data!=10; - if (isCompressed) - return ParseCompressed(data,dataLen); - else - return ParseTag(data); - } - - void PrintTree(NbtTag &tree, int deepness = 0, std::ostream &ostream = std::cout) { - ostream << std::string(deepness, '\t') << "Tag "; - switch (tree.GetType()) { - case Byte: - ostream << "byte"; - break; - case Short: - ostream << "short"; - break; - case Int: - ostream << "int"; - break; - case Long: - ostream << "long"; - break; - case Float: - ostream << "float"; - break; - case Double: - ostream << "double"; - break; - case ByteArray: - ostream << "byte array"; - break; - case String: - ostream << "string"; - break; - case List: - ostream << "list"; - break; - case Compound: - ostream << "compound"; - break; - case IntArray: - ostream << "int array"; - break; - case End: - ostream << "end"; - break; - } - if (tree.GetName().length() > 0) - ostream << " (" << tree.GetName() << ")"; - ostream << ": "; - - if (tree.GetType() == Compound || tree.GetType() == List) { - std::vector &vec = (tree.GetType() == Compound ? tree.GetCompound() : tree.GetList()); - ostream << vec.size() << " entries {" << std::endl; - for (auto it = vec.begin(); it != vec.end(); ++it) { - PrintTree(*it, deepness + 1, std::cout); - } - ostream << std::string(deepness, '\t') << "}" << std::endl; - return; - } else { - switch (tree.GetType()) { - case Int: - ostream << tree.GetInt(); - break; - case String: - ostream << "\"" << tree.GetString() << "\""; - break; - case Double: - ostream << tree.GetDouble(); - break; - case Float: - ostream << tree.GetFloat(); - break; - case Short: - ostream << tree.GetShort(); - break; - case Byte: - ostream << (int) tree.GetByte(); - break; - case Long: - ostream << tree.GetLong(); - break; - case ByteArray: - ostream << "[" << tree.GetByteArray().size() << " bytes]: "; - for (int i = 0; i < (tree.GetByteArray().size() > 10 ? 10 : tree.GetByteArray().size()); i++) { - ostream << std::hex << "0x" << (tree.GetByteArray()[i] > 15 ? "" : "0") - << (int) tree.GetByteArray()[i] - << std::dec << " "; - } - break; - case IntArray: - break; - } - ostream << std::endl; - } - } -} \ No newline at end of file diff --git a/src/network/Network.cpp b/src/network/Network.cpp index 68df158..91cb481 100644 --- a/src/network/Network.cpp +++ b/src/network/Network.cpp @@ -1,5 +1,4 @@ -#include "Network.hpp" -#include +#include Network::Network(std::string address, unsigned short port) { socket = new Socket(address, port); diff --git a/src/network/Network.hpp b/src/network/Network.hpp deleted file mode 100644 index 1281289..0000000 --- a/src/network/Network.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include -#include "Socket.hpp" -#include "Packet.hpp" - -enum ConnectionState { - Handshaking, - Login, - Play, - Status, -}; - -class Network { - Socket *socket; - StreamSocket *stream; - - std::shared_ptr ReceivePacketByPacketId(int packetId, ConnectionState state, StreamInput &stream); -public: - Network(std::string address, unsigned short port); - ~Network(); - - std::shared_ptr ReceivePacket(ConnectionState state = Play); - void SendPacket(Packet &packet); - std::shared_ptr ParsePacketPlay(PacketNamePlayCB id); -}; \ No newline at end of file diff --git a/src/network/NetworkClient.cpp b/src/network/NetworkClient.cpp index b8d880d..73880cf 100644 --- a/src/network/NetworkClient.cpp +++ b/src/network/NetworkClient.cpp @@ -1,5 +1,4 @@ -#include "NetworkClient.hpp" -#include "Packet.hpp" +#include NetworkClient::NetworkClient(std::string address, unsigned short port, std::string username, bool &quit) : network(address, port), isRunning(quit) { diff --git a/src/network/NetworkClient.hpp b/src/network/NetworkClient.hpp deleted file mode 100644 index bf7aa4e..0000000 --- a/src/network/NetworkClient.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include -#include -#include -#include "Network.hpp" - -class NetworkClient { - Network network; - std::thread networkThread; - std::mutex toSendMutex; - std::mutex toReceiveMutex; - std::queue > toSend; - std::queue > toReceive; - bool isActive=true; - bool &isRunning; - ConnectionState state; - void NetworkLoop(); -public: - NetworkClient(std::string address, unsigned short port, std::string username, bool &quit); - ~NetworkClient(); - - std::shared_ptr ReceivePacket(); - void SendPacket(std::shared_ptr packet); -}; \ No newline at end of file diff --git a/src/network/Packet.hpp b/src/network/Packet.hpp deleted file mode 100644 index 3cf4d26..0000000 --- a/src/network/Packet.hpp +++ /dev/null @@ -1,520 +0,0 @@ -#pragma once - -#include -#include "Stream.hpp" - -enum PacketNameLoginSB { - LoginStart = 0x00, - EncryptionResponse = 0x01, -}; -enum PacketNamePlaySB { - TeleportConfirm, - PrepareCraftingGrid, - TabCompleteSB, - ChatMessageSB, - ClientStatus, - ClientSettings, - ConfirmTransactionSB, - EnchantItem, - ClickWindow, - CloseWindowSB, - PluginMessageSB, - UseEntity, - KeepAliveSB, - Player, - PlayerPosition, - PlayerPositionAndLookSB, - PlayerLook, - VehicleMoveSB, - SteerBoat, - PlayerAbilitiesSB, - PlayerDigging, - EntityAction, - SteerVehicle, - CraftingBookData, - ResourcePackStatus, - AdvancementTab, - HeldItemChangeSB, - CreativeInventoryAction, - UpdateSign, - AnimationSB, - Spectate, - PlayerBlockPlacement, - UseItem, -}; - -enum PacketNameHandshakingCB { - Handshake = 0x00, -}; -enum PacketNameLoginCB { - Disconnect = 0x00, - EncryptionRequest = 0x01, - LoginSuccess = 0x02, - SetCompression = 0x03, -}; -enum PacketNamePlayCB { - SpawnObject = 0x00, - SpawnExperienceOrb, - SpawnGlobalEntity, - SpawnMob, - SpawnPainting, - SpawnPlayer, - AnimationCB, - Statistics, - BlockBreakAnimation, - UpdateBlockEntity, - BlockAction, - BlockChange, - BossBar, - ServerDifficulty, - TabCompleteCB, - ChatMessageCB, - MultiBlockChange, - ConfirmTransactionCB, - CloseWindowCB, - OpenWindow, - WindowItems, - WindowProperty, - SetSlot, - SetCooldown, - PluginMessageCB, - NamedSoundEffect, - DisconnectPlay, - EntityStatus, - Explosion, - UnloadChunk, - ChangeGameState, - KeepAliveCB, - ChunkData, - Effect, - Particle, - JoinGame, - Map, - EntityRelativeMove, - EntityLookAndRelativeMove, - EntityLook, - Entity, - VehicleMove, - OpenSignEditor, - PlayerAbilitiesCB, - CombatEvent, - PlayerListItem, - PlayerPositionAndLookCB, - UseBed, - UnlockRecipes, - DestroyEntities, - RemoveEntityEffect, - ResourcePackSend, - Respawn, - EntityHeadLook, - SelectAdvancementTab, - WorldBorder, - Camera, - HeldItemChangeCB, - DisplayScoreboard, - EntityMetadata, - AttachEntity, - EntityVelocity, - EntityEquipment, - SetExperience, - UpdateHealth, - ScoreboardObjective, - SetPassengers, - Teams, - UpdateScore, - SpawnPosition, - TimeUpdate, - Title, - SoundEffect, - PlayerListHeaderAndFooter, - CollectItem, - EntityTeleport, - Advancements, - EntityProperties, - EntityEffect, -}; - -struct Packet { - virtual ~Packet() = default; - virtual void ToStream(StreamOutput *stream) = 0; - virtual void FromStream(StreamInput *stream) = 0; - virtual int GetPacketId() = 0; -}; - -struct PacketHandshake : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteVarInt(protocolVersion); - stream->WriteString(serverAddress); - stream->WriteUShort(serverPort); - stream->WriteVarInt(nextState); - } - - void FromStream(StreamInput *stream) override { - protocolVersion = stream->ReadVarInt(); - serverAddress = stream->ReadString(); - serverPort = stream->ReadUShort(); - nextState = stream->ReadVarInt(); - } - - int GetPacketId() override { - return PacketNameHandshakingCB::Handshake; - } - - int protocolVersion; - std::string serverAddress; - unsigned short serverPort; - int nextState; -}; - -struct PacketLoginStart : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteString(Username); - } - - void FromStream(StreamInput *stream) override { - Username = stream->ReadString(); - } - - int GetPacketId() override { - return PacketNameLoginSB::LoginStart; - } - - std::string Username; -}; - -struct PacketLoginSuccess : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteString(Uuid); - stream->WriteString(Username); - } - - void FromStream(StreamInput *stream) override { - Uuid = stream->ReadString(); - Username = stream->ReadString(); - } - - int GetPacketId() override { - return PacketNameLoginCB::LoginSuccess; - } - - std::string Uuid; - std::string Username; -}; - -struct PacketJoinGame : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteInt(EntityId); - stream->WriteUByte(Gamemode); - stream->WriteInt(Dimension); - stream->WriteUByte(Difficulty); - stream->WriteUByte(MaxPlayers); - stream->WriteString(LevelType); - stream->WriteBool(ReducedDebugInfo); - } - - void FromStream(StreamInput *stream) override { - EntityId = stream->ReadInt(); - Gamemode = stream->ReadUByte(); - Dimension = stream->ReadInt(); - Difficulty = stream->ReadUByte(); - MaxPlayers = stream->ReadUByte(); - LevelType = stream->ReadString(); - ReducedDebugInfo = stream->ReadBool(); - } - - int GetPacketId() override { - return PacketNamePlayCB::JoinGame; - } - - int EntityId; - unsigned char Gamemode; - int Dimension; - unsigned char Difficulty; - unsigned char MaxPlayers; - std::string LevelType; - bool ReducedDebugInfo; -}; - -struct PacketDisconnectPlay : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteString(Reason); //TODO: Implement chat-wrapper - } - - void FromStream(StreamInput *stream) override { - Reason = stream->ReadChat(); - } - - int GetPacketId() override { - return PacketNamePlayCB::DisconnectPlay; - } - - std::string Reason; -}; - -struct PacketSpawnPosition : Packet { - void ToStream(StreamOutput *stream) override { - stream->WritePosition(Location); - } - - void FromStream(StreamInput *stream) override { - Location = stream->ReadPosition(); - } - - int GetPacketId() override { - return PacketNamePlayCB::SpawnPosition; - } - - Vector Location; -}; - -struct PacketKeepAliveCB : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteVarInt(KeepAliveId); - } - - void FromStream(StreamInput *stream) override { - KeepAliveId = stream->ReadVarInt(); - } - - int GetPacketId() override { - return PacketNamePlayCB::KeepAliveCB; - } - - int KeepAliveId; -}; - -struct PacketKeepAliveSB : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteVarInt(KeepAliveId); - } - - void FromStream(StreamInput *stream) override { - KeepAliveId = stream->ReadVarInt(); - } - - int GetPacketId() override { - return PacketNamePlaySB::KeepAliveSB; - } - - int KeepAliveId; - - PacketKeepAliveSB(int KeepAliveId) : KeepAliveId(KeepAliveId) {} -}; - -struct PacketPlayerPositionAndLookCB : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteDouble(X); - stream->WriteDouble(Y); - stream->WriteDouble(Z); - stream->WriteFloat(Yaw); - stream->WriteFloat(Pitch); - stream->WriteUByte(Flags); - stream->WriteVarInt(TeleportId); - } - - void FromStream(StreamInput *stream) override { - X = stream->ReadDouble(); - Y = stream->ReadDouble(); - Z = stream->ReadDouble(); - Yaw = stream->ReadFloat(); - Pitch = stream->ReadFloat(); - Flags = stream->ReadUByte(); - TeleportId = stream->ReadVarInt(); - } - - int GetPacketId() override { - return PacketNamePlayCB::PlayerPositionAndLookCB; - } - - double X; - double Y; - double Z; - float Yaw; - float Pitch; - unsigned char Flags; - int TeleportId; -}; - -struct PacketTeleportConfirm : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteVarInt(TeleportId); - } - - void FromStream(StreamInput *stream) override { - TeleportId = stream->ReadVarInt(); - } - - int GetPacketId() override { - return PacketNamePlaySB::TeleportConfirm; - } - - int TeleportId; - - PacketTeleportConfirm(int TeleportId) : TeleportId(TeleportId) {} -}; - -struct PacketClientStatus : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteVarInt(ActionId); - } - - void FromStream(StreamInput *stream) override { - ActionId = stream->ReadVarInt(); - } - - int GetPacketId() override { - return PacketNamePlaySB::ClientStatus; - } - - int ActionId; - - PacketClientStatus(int ActionId) : ActionId(ActionId) {} -}; - -struct PacketPlayerPositionAndLookSB : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteDouble(X); - stream->WriteDouble(FeetY); - stream->WriteDouble(Z); - stream->WriteFloat(Yaw); - stream->WriteFloat(Pitch); - stream->WriteBool(OnGround); - } - - void FromStream(StreamInput *stream) override { - X = stream->ReadDouble(); - FeetY = stream->ReadDouble(); - Z = stream->ReadDouble(); - Yaw = stream->ReadFloat(); - Pitch = stream->ReadFloat(); - OnGround = stream->ReadBool(); - } - - int GetPacketId() override { - return PacketNamePlaySB::PlayerPositionAndLookSB; - } - - - double X; - double FeetY; - double Z; - float Yaw; - float Pitch; - bool OnGround; - - PacketPlayerPositionAndLookSB(double X, double FeetY, double Z, - float Yaw, float Pitch, bool OnGround) : X(X), FeetY(FeetY), Z(Z), Yaw(Yaw), - Pitch(Pitch), OnGround(OnGround) {} -}; - -struct PacketChunkData : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteInt(ChunkX); - stream->WriteInt(ChunkZ); - stream->WriteBool(GroundUpContinuous); - stream->WriteInt(PrimaryBitMask); - stream->WriteVarInt(Data.size()); - stream->WriteByteArray(Data); - stream->WriteVarInt(BlockEntities.size()); - LOG(FATAL) << "Serializing unimplemented packet"; - } - - void FromStream(StreamInput *stream) override { - ChunkX = stream->ReadInt(); - ChunkZ = stream->ReadInt(); - GroundUpContinuous = stream->ReadBool(); - PrimaryBitMask = stream->ReadVarInt(); - int Size = stream->ReadVarInt(); - Data = stream->ReadByteArray(Size); - int NumberOfBlockEntities = stream->ReadVarInt(); //TODO: Need NBT - for (int i = 0; i < NumberOfBlockEntities; i++) { - //BlockEntities[i] = stream->ReadNbt(); - } - } - - int GetPacketId() override { - return PacketNamePlayCB::ChunkData; - } - - int ChunkX; - int ChunkZ; - bool GroundUpContinuous; - int PrimaryBitMask; - //int Size; - std::vector Data; - //int NumberOfBlockEntities; - std::vector BlockEntities; //TODO: Replace int with NbtTag and implement NbtTree -}; - -struct PacketPlayerPosition : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteDouble(X); - stream->WriteDouble(FeetY); - stream->WriteDouble(Z); - stream->WriteBool(OnGround); - } - - void FromStream(StreamInput *stream) override { - X = stream->ReadDouble(); - FeetY = stream->ReadDouble(); - Z = stream->ReadDouble(); - OnGround = stream->ReadBool(); - } - - int GetPacketId() override { - return PacketNamePlaySB::PlayerPosition; - } - - double X; - double FeetY; - double Z; - bool OnGround; - - PacketPlayerPosition(double X, double Y, double Z, bool ground) : X(X), FeetY(Y), Z(Z), OnGround(ground) {} -}; - -struct PacketPlayerLook : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteFloat(Yaw); - stream->WriteFloat(Pitch); - stream->WriteBool(OnGround); - } - - void FromStream(StreamInput *stream) override { - Yaw = stream->ReadFloat(); - Pitch = stream->ReadFloat(); - OnGround = stream->ReadBool(); - } - - int GetPacketId() override { - return PacketNamePlaySB::PlayerLook; - } - - float Yaw; - float Pitch; - bool OnGround; - - PacketPlayerLook(float Yaw, float Pitch, bool ground) : Yaw(Yaw), Pitch(Pitch), OnGround(ground) {} -}; - -struct PacketUpdateHealth : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteFloat(Health); - stream->WriteVarInt(Food); - stream->WriteFloat(FoodSaturation); - } - - void FromStream(StreamInput *stream) override { - Health = stream->ReadFloat(); - Food = stream->ReadVarInt(); - FoodSaturation = stream->ReadFloat(); - } - - int GetPacketId() override { - return PacketNamePlayCB::UpdateHealth; - } - - float Health; - int Food; - float FoodSaturation; -}; \ No newline at end of file diff --git a/src/network/Socket.cpp b/src/network/Socket.cpp index 2bbf49a..f4e6787 100644 --- a/src/network/Socket.cpp +++ b/src/network/Socket.cpp @@ -1,4 +1,4 @@ -#include "Socket.hpp" +#include Socket::Socket(std::string address, unsigned short port) { sf::Socket::Status connectionStatus = socket.connect(sf::IpAddress(address), port); diff --git a/src/network/Socket.hpp b/src/network/Socket.hpp deleted file mode 100644 index ee449b3..0000000 --- a/src/network/Socket.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include -#include - -/** - * Platform independent class for working with platform dependent hardware socket - * @brief Wrapper around raw sockets - * @warning Connection state is based on lifetime of Socket object instance, ie connected at ctor and disconnect at dtor - * @todo Replace SFML's socket with WinSock and POSIX's socket implementation - */ -class Socket { - sf::TcpSocket socket; -public: - /** - * Constructs Socket class instance from IP's string and Port number and connects to remote server - * @param[in] address IP address of remote server. String should be ANSI and contains 4 one-byte values separated by dots - * @param[in] port target port of remote server to connect - * @throw std::runtime_error if connection is failed - */ - Socket(std::string address, unsigned short port); - - /** - * Destruct Socket instance and disconnect from server - * @warning There is no way to force disconnect, except use delete for manually allocated objects and scope of visibility for variables on stack - */ - ~Socket(); - - /** - * Reads data from socket and write to buffer - * @warning This is blocking function, and execution flow will not be returned until all required data is sended - * @warning Reported buffer length must be <= actual size of buffer, or memory corruption will be caused - * @param[out] buffPtr Pointer to buffer, where data must be placed - * @param[in] buffLen Length of data, that must be readed from server and writed to buffer - */ - void Read(unsigned char *buffPtr, size_t buffLen); - - /** - * Writes data from buffer to socket - * @warning This is blocking function, and execution flow will not be returned until all required data is received - * @param[in] buffPtr Pointer to buffer that contain data to send - * @param[in] buffLen Length of buffer - */ - void Write(unsigned char *buffPtr, size_t buffLen); -}; \ No newline at end of file diff --git a/src/network/Stream.cpp b/src/network/Stream.cpp index d492428..447b13f 100644 --- a/src/network/Stream.cpp +++ b/src/network/Stream.cpp @@ -1,4 +1,4 @@ -#include "Stream.hpp" +#include const int MAX_VARINT_LENGTH = 5; diff --git a/src/network/Stream.hpp b/src/network/Stream.hpp deleted file mode 100644 index 5babb08..0000000 --- a/src/network/Stream.hpp +++ /dev/null @@ -1,115 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include "Socket.hpp" -#include "../utility/Vector.hpp" - -class Stream { -protected: - template - void endswap(T &obj) { - unsigned char *raw = reinterpret_cast(&obj); - std::reverse(raw, raw + sizeof(T)); - } - - void endswap(unsigned char *arr, size_t arrLen) { - std::reverse(arr, arr + arrLen); - } - -public: - virtual ~Stream() {}; -}; - -class StreamInput : Stream { - virtual void ReadData(unsigned char *buffPtr, size_t buffLen) = 0; -public: - virtual ~StreamInput() = default; - bool ReadBool(); - signed char ReadByte(); - unsigned char ReadUByte(); - short ReadShort(); - unsigned short ReadUShort(); - int ReadInt(); - long long ReadLong(); - float ReadFloat(); - double ReadDouble(); - std::string ReadString(); - std::string ReadChat(); - int ReadVarInt(); - long long ReadVarLong(); - std::vector ReadEntityMetadata(); - std::vector ReadSlot(); - std::vector ReadNbtTag(); - Vector ReadPosition(); - unsigned char ReadAngle(); - std::vector ReadUuid(); - std::vector ReadByteArray(size_t arrLength); -}; - -class StreamOutput : Stream { - virtual void WriteData(unsigned char *buffPtr, size_t buffLen) = 0; -public: - virtual ~StreamOutput() = default; - void WriteBool(bool value); - void WriteByte(signed char value); - void WriteUByte(unsigned char value); - void WriteShort(short value); - void WriteUShort(unsigned short value); - void WriteInt(int value); - void WriteLong(long long value); - void WriteFloat(float value); - void WriteDouble(double value); - void WriteString(std::string value); - void WriteChat(std::string value); - void WriteVarInt(int value); - void WriteVarLong(long long value); - void WriteEntityMetadata(std::vector value); - void WriteSlot(std::vector value); - void WriteNbtTag(std::vector value); - void WritePosition(Vector value); - void WriteAngle(unsigned char value); - void WriteUuid(std::vector value); - void WriteByteArray(std::vector value); -}; - -class StreamBuffer : public StreamInput, public StreamOutput { - unsigned char *buffer; - unsigned char *bufferPtr; - size_t bufferLength; - - void ReadData(unsigned char *buffPtr, size_t buffLen) override; - void WriteData(unsigned char *buffPtr, size_t buffLen) override; - -public: - StreamBuffer(unsigned char *data, size_t dataLen); - StreamBuffer(size_t bufferLen); - ~StreamBuffer(); - - std::vector GetBuffer(); -}; - -class StreamCounter : public StreamOutput { - void WriteData(unsigned char *buffPtr, size_t buffLen) override; - - size_t size; -public: - StreamCounter(size_t initialSize = 0); - ~StreamCounter(); - - size_t GetCountedSize(); -}; - -class StreamSocket : public StreamInput, public StreamOutput { - Socket *socket; - void ReadData(unsigned char *buffPtr, size_t buffLen) override; - void WriteData(unsigned char *buffPtr, size_t buffLen) override; -public: - StreamSocket(Socket *socketPtr); - ~StreamSocket() = default; -}; \ No newline at end of file diff --git a/src/utility/Vector.hpp b/src/utility/Vector.hpp deleted file mode 100644 index 9d6c1be..0000000 --- a/src/utility/Vector.hpp +++ /dev/null @@ -1,123 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -template -class Vector3 { - T x, y, z; -public: - Vector3(T X = 0, T Y = 0, T Z = 0) : x(X), y(Y), z(Z) {} - - Vector3(const Vector3 &rhs) : x(rhs.x), y(rhs.y), z(rhs.z) {} - - ~Vector3() = default; - - void SetX(T X) { x = X; } - - void SetY(T Y) { y = Y; } - - void SetZ(T Z) { z = Z; } - - T GetX() const { return x; } - - T GetY() const { return y; } - - T GetZ() const { return z; } - - double GetMagnitude() const { return std::sqrt(std::pow(x, 2) + std::pow(y, 2) + std::pow(z, 2)); } - - operator glm::vec3() const { - return glm::vec3(x, y, z); - } - - void swap(Vector3 &rhs) { - std::swap(x, rhs.x); - std::swap(y, rhs.y); - std::swap(z, rhs.z); - } - - Vector3 &operator=(Vector3 rhs) { - rhs.swap(*this); - return *this; - } - - Vector3 operator*(T rhs) const { - return Vector3( - x * rhs, - y * rhs, - z * rhs - ); - } - - Vector3 operator/(T rhs) const { - return Vector3( - x / rhs, - y / rhs, - z / rhs - ); - } - - Vector3 operator+(const Vector3 &rhs) const { - return Vector3( - x + rhs.x, - y + rhs.y, - z + rhs.z - ); - } - - Vector3 operator-(const Vector3 &rhs) const { - return Vector3( - x - rhs.x, - y - rhs.y, - z - rhs.z - ); - } - - Vector3 operator*(const Vector3 &rhs) const { - return Vector3( - x * rhs.x, - y * rhs.y, - z * rhs.z - ); - } - - Vector3 operator/(const Vector3 &rhs) const { - return Vector3( - x / rhs.x, - y / rhs.y, - z / rhs.z - ); - } - - bool operator==(const Vector3 &rhs) const { - return (x == rhs.x && y == rhs.y && z == rhs.z); - } - - bool operator!=(const Vector3 &rhs) const { - return !(*this == rhs); - } - - bool operator<(const Vector3 &rhs) const { - //return (x < rhs.x || y < rhs.y ||z z < rhs.z); - /*if (x < rhs.x) - return true; - else if (z < rhs.z) - return true; - else if (y < rhs.y) - return true; - return false;*/ - return std::tie(x, y, z) < std::tie(rhs.x, rhs.y, rhs.z); - } - - - friend std::ostream &operator<<(std::ostream &os, const Vector3 &vector3) { - os << vector3.x << ", " << vector3.y << ", " << vector3.z; - return os; - } -}; - -typedef Vector3 VectorF; -typedef Vector3 Vector; \ No newline at end of file diff --git a/src/utility/utility.cpp b/src/utility/utility.cpp deleted file mode 100644 index aa50e9f..0000000 --- a/src/utility/utility.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "utility.h" - -int VarIntRead(unsigned char *data, size_t &readed) { - readed = 0; - int result = 0; - char read; - do { - read = data[readed]; - int value = (read & 0b01111111); - result |= (value << (7 * readed)); - - readed++; - if (readed > 5) { - throw "VarInt is too big"; - } - } while ((read & 0b10000000) != 0); - - return result; -} - -size_t VarIntWrite(unsigned int value, unsigned char *data) { - size_t len = 0; - do { - unsigned char temp = (unsigned char) (value & 0b01111111); - value >>= 7; - if (value != 0) { - temp |= 0b10000000; - } - data[len] = temp; - len++; - } while (value != 0); - return len; -} - -long long int ReadVarLong(unsigned char *data, int &readed) { - readed = 0; - long long result = 0; - unsigned char read; - do { - read = data[readed]; - long long value = (read & 0b01111111); - result |= (value << (7 * readed)); - - readed++; - if (readed > 10) { - throw "VarLong is too big"; - } - } while ((read & 0b10000000) != 0); - return result; -} - -unsigned char *WriteVarLong(unsigned long long int value, int &len) { - unsigned char *data = new unsigned char[10]; - len = 0; - do { - unsigned char temp = (unsigned char) (value & 0b01111111); - value >>= 7; - if (value != 0) { - temp |= 0b10000000; - } - data[len] = temp; - len++; - } while (value != 0); - - return data; -} \ No newline at end of file diff --git a/src/utility/utility.h b/src/utility/utility.h deleted file mode 100644 index 32120cb..0000000 --- a/src/utility/utility.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once -#include - -int VarIntRead(unsigned char *data, size_t &readed); - -size_t VarIntWrite(unsigned int value, unsigned char *data); - -long long int ReadVarLong(unsigned char *data, int &readed); - -unsigned char *WriteVarLong(unsigned long long int value, int &len); - -template -void endswap(T *objp) { - unsigned char *memp = reinterpret_cast(objp); - std::reverse(memp, memp + sizeof(T)); -} \ No newline at end of file diff --git a/src/world/Block.cpp b/src/world/Block.cpp index e88068a..74ac406 100644 --- a/src/world/Block.cpp +++ b/src/world/Block.cpp @@ -1,4 +1,4 @@ -#include "Block.hpp" +#include Block::~Block() {} diff --git a/src/world/Block.hpp b/src/world/Block.hpp deleted file mode 100644 index 2f823fe..0000000 --- a/src/world/Block.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -struct Block { - Block(); - - Block(unsigned short id, unsigned char state); - - ~Block(); - - unsigned short id : 13; - unsigned char state : 4; - //unsigned char light:4; -}; - -bool operator<(const Block &lhs, const Block &rhs); \ No newline at end of file diff --git a/src/world/Collision.cpp b/src/world/Collision.cpp index 4f2c837..8fc562b 100644 --- a/src/world/Collision.cpp +++ b/src/world/Collision.cpp @@ -1,4 +1,4 @@ -#include "Collision.hpp" +#include bool TestCollision(AABB first, AABB second) { double firstXl = first.x; diff --git a/src/world/Collision.hpp b/src/world/Collision.hpp deleted file mode 100644 index b88fbf7..0000000 --- a/src/world/Collision.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -struct AABB { - double x,y,z; - double w,l,h; -}; - -bool TestCollision(AABB first, AABB second); \ No newline at end of file diff --git a/src/world/GameState.cpp b/src/world/GameState.cpp new file mode 100644 index 0000000..b484b06 --- /dev/null +++ b/src/world/GameState.cpp @@ -0,0 +1,389 @@ +#include + +GameState::GameState(NetworkClient *Net, bool &quit) : nc(Net), isRunning(quit) { + Front = glm::vec3(0.0f, 0.0f, -1.0f); + this->SetPosition(glm::vec3(0.0f, 0.0f, 3.0f)); + this->WorldUp = glm::vec3(0.0f, 1.0f, 0.0f); + this->updateCameraVectors(); +} + +void GameState::Update(float deltaTime) { + if (g_IsGameStarted) { + std::chrono::steady_clock clock; + static auto timeOfPreviousSendedPacket(clock.now()); + auto delta = clock.now() - timeOfPreviousSendedPacket; + using namespace std::chrono_literals; + if (delta >= 50ms) { + nc->SendPacket(std::make_shared(g_PlayerX, g_PlayerY, g_PlayerZ, g_PlayerYaw, + g_PlayerPitch, g_OnGround)); + timeOfPreviousSendedPacket = clock.now(); + } + + const float gravity = -9.8f; + g_PlayerVelocityY += gravity * deltaTime; + + bool isCollides = world.isPlayerCollides(g_PlayerX, g_PlayerY + g_PlayerVelocityY * deltaTime, + g_PlayerZ); + if (!isCollides) { + g_PlayerY += g_PlayerVelocityY * deltaTime; + g_OnGround = false; + } else { + g_PlayerVelocityY = 0; + if (g_OnGround == false) { + auto updatePacket = std::make_shared(g_PlayerX, g_PlayerY, g_PlayerZ, true); + nc->SendPacket(updatePacket); + } + g_OnGround = true; + } + + isCollides = world.isPlayerCollides(g_PlayerX + g_PlayerVelocityX * deltaTime, g_PlayerY, + g_PlayerZ + g_PlayerVelocityZ * deltaTime); + if (!isCollides) { + g_PlayerX += g_PlayerVelocityX * deltaTime; + g_PlayerZ += g_PlayerVelocityZ * deltaTime; + } + + const float AirResistance = 10.0f; + glm::vec3 vel(g_PlayerVelocityX, 0, g_PlayerVelocityZ); + glm::vec3 resistForce = -vel * AirResistance * deltaTime; + vel += resistForce; + g_PlayerVelocityX = vel.x; + g_PlayerVelocityZ = vel.z; + } + + + //Packet handling + auto ptr = nc->ReceivePacket(); + while (ptr != nullptr) { + switch ((PacketNamePlayCB) ptr->GetPacketId()) { + case SpawnObject: + break; + case SpawnExperienceOrb: + break; + case SpawnGlobalEntity: + break; + case SpawnMob: + break; + case SpawnPainting: + break; + case SpawnPlayer: + break; + case AnimationCB: + break; + case Statistics: + break; + case BlockBreakAnimation: + break; + case UpdateBlockEntity: + break; + case BlockAction: + break; + case BlockChange: + break; + case BossBar: + break; + case ServerDifficulty: + break; + case TabCompleteCB: + break; + case ChatMessageCB: + break; + case MultiBlockChange: + break; + case ConfirmTransactionCB: + break; + case CloseWindowCB: + break; + case OpenWindow: + break; + case WindowItems: + break; + case WindowProperty: + break; + case SetSlot: + break; + case SetCooldown: + break; + case PluginMessageCB: + break; + case NamedSoundEffect: + break; + case DisconnectPlay: { + auto packet = std::static_pointer_cast(ptr); + LOG(INFO) << "Disconnect reason: " << packet->Reason; + isRunning = false; + break; + } + case EntityStatus: + break; + case Explosion: + break; + case UnloadChunk: + break; + case ChangeGameState: + break; + case KeepAliveCB: + LOG(WARNING) << "Receive KeepAlive packet in GameState handler"; + break; + case ChunkData: { + auto packet = std::static_pointer_cast(ptr); + world.ParseChunkData(packet); + break; + } + case Effect: + break; + case Particle: + break; + case JoinGame: { + auto packet = std::static_pointer_cast(ptr); + g_PlayerEid = packet->EntityId; + g_Gamemode = (packet->Gamemode & 0b11111011); + g_Dimension = packet->Dimension; + g_Difficulty = packet->Difficulty; + g_MaxPlayers = packet->MaxPlayers; + g_LevelType = packet->LevelType; + g_ReducedDebugInfo = packet->ReducedDebugInfo; + LOG(INFO) << "Gamemode is " << g_Gamemode << ", Difficulty is " << (int) g_Difficulty + << ", Level Type is " << g_LevelType; + break; + } + case Map: + break; + case EntityRelativeMove: + break; + case EntityLookAndRelativeMove: + break; + case EntityLook: + break; + case Entity: + break; + case VehicleMove: + break; + case OpenSignEditor: + break; + case PlayerAbilitiesCB: + break; + case CombatEvent: + break; + case PlayerListItem: + break; + case PlayerPositionAndLookCB: { + auto packet = std::static_pointer_cast(ptr); + if ((packet->Flags & 0x10) != 0) { + g_PlayerPitch += packet->Pitch; + } else { + g_PlayerPitch = packet->Pitch; + }; + + if ((packet->Flags & 0x08) != 0) { + g_PlayerYaw += packet->Yaw; + } else { + g_PlayerYaw = packet->Yaw; + } + + if ((packet->Flags & 0x01) != 0) { + g_PlayerX += packet->X; + } else { + g_PlayerX = packet->X; + } + + if ((packet->Flags & 0x02) != 0) { + g_PlayerY += packet->Y; + } else { + g_PlayerY = packet->Y; + } + + if ((packet->Flags & 0x04) != 0) { + g_PlayerZ += packet->Z; + } else { + g_PlayerZ = packet->Z; + } + + //if (!g_IsGameStarted) + LOG(INFO) << "PlayerPos is " << g_PlayerX << ", " << g_PlayerY << ", " << g_PlayerZ << "\t\tAngle: " + << g_PlayerYaw << "," << g_PlayerPitch; + + g_IsGameStarted = true; + + auto packetResponse = std::make_shared(packet->TeleportId); + auto packetPerformRespawn = std::make_shared(0); + + nc->SendPacket(packetResponse); + nc->SendPacket(packetPerformRespawn); + break; + } + case UseBed: + break; + case UnlockRecipes: + break; + case DestroyEntities: + break; + case RemoveEntityEffect: + break; + case ResourcePackSend: + break; + case Respawn: + break; + case EntityHeadLook: + break; + case SelectAdvancementTab: + break; + case WorldBorder: + break; + case Camera: + break; + case HeldItemChangeCB: + break; + case DisplayScoreboard: + break; + case EntityMetadata: + break; + case AttachEntity: + break; + case EntityVelocity: + break; + case EntityEquipment: + break; + case SetExperience: + break; + case UpdateHealth: { + auto packet = std::static_pointer_cast(ptr); + g_PlayerHealth = packet->Health; + if (g_PlayerHealth <= 0) { + LOG(INFO) << "Player is dead. Respawning..."; + auto packetPerformRespawn = std::make_shared(0); + nc->SendPacket(packetPerformRespawn); + } + break; + } + case ScoreboardObjective: + break; + case SetPassengers: + break; + case Teams: + break; + case UpdateScore: + break; + case SpawnPosition: { + auto packet = std::static_pointer_cast(ptr); + g_SpawnPosition = packet->Location; + LOG(INFO) << "Spawn position is " << g_SpawnPosition.GetX() << "," << g_SpawnPosition.GetY() << "," + << g_SpawnPosition.GetZ(); + break; + } + case TimeUpdate: + break; + case Title: + break; + case SoundEffect: + break; + case PlayerListHeaderAndFooter: + break; + case CollectItem: + break; + case EntityTeleport: + break; + case Advancements: + break; + case EntityProperties: + break; + case EntityEffect: + break; + } + ptr = nc->ReceivePacket(); + } +} + +void GameState::HandleMovement(GameState::Direction direction, float deltaTime) { + const float PlayerSpeed = 40.0; + float velocity = PlayerSpeed * deltaTime; + glm::vec3 vel(g_PlayerVelocityX, g_PlayerVelocityY, g_PlayerVelocityZ); + glm::vec3 front(cos(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch())), 0, + sin(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch()))); + front = glm::normalize(front); + glm::vec3 right = glm::normalize(glm::cross(front, this->WorldUp)); + switch (direction) { + case FORWARD: + vel += front * velocity; + break; + case BACKWARD: + vel -= front * velocity; + break; + case RIGHT: + vel += right * velocity; + break; + case LEFT: + vel -= right * velocity; + break; + case JUMP: + if (g_OnGround) { + vel.y += 5; + g_OnGround = false; + } + break; + } + g_PlayerVelocityX = vel.x; + g_PlayerVelocityY = vel.y; + g_PlayerVelocityZ = vel.z; + + /*bool isCollides = world.isPlayerCollides(g_PlayerX, g_PlayerY, g_PlayerZ); + if (isCollides) { + SetPosition(previousPos); + return; + } + auto updatePacket = std::make_shared(g_PlayerX, g_PlayerY, g_PlayerZ, true); + nc->SendPacket(updatePacket);*/ +} + +void GameState::HandleRotation(double yaw, double pitch) { + this->SetYaw(Yaw() + yaw); + this->SetPitch(Pitch() + pitch); + if (this->Pitch() > 89.0f) + this->SetPitch(89.0f); + if (this->Pitch() < -89.0f) + this->SetPitch(-89.0f); + this->updateCameraVectors(); + + auto updatePacket = std::make_shared(g_PlayerYaw, g_PlayerPitch, g_OnGround); + nc->SendPacket(updatePacket); +} + +glm::mat4 GameState::GetViewMatrix() { + return glm::lookAt(this->Position(), this->Position() + this->Front, this->Up); +} + +void GameState::updateCameraVectors() { + glm::vec3 front; + front.x = cos(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch())); + front.y = sin(glm::radians(this->Pitch())); + front.z = sin(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch())); + this->Front = glm::normalize(front); + this->Right = glm::normalize(glm::cross(this->Front, this->WorldUp)); + this->Up = glm::normalize(glm::cross(this->Right, this->Front)); +} + +float GameState::Yaw() { + return g_PlayerYaw + 90; +} + +float GameState::Pitch() { + return -g_PlayerPitch; +} + +void GameState::SetYaw(float yaw) { + g_PlayerYaw = yaw - 90; +} + +void GameState::SetPitch(float pitch) { + g_PlayerPitch = -pitch; +} + +glm::vec3 GameState::Position() { + return glm::vec3(g_PlayerX - 0.5, g_PlayerY + 1.12, g_PlayerZ - 0.5); +} + +void GameState::SetPosition(glm::vec3 Position) { + g_PlayerX = Position.x + 0.5; + g_PlayerY = Position.y - 1.12; + g_PlayerZ = Position.z + 0.5; +} diff --git a/src/world/Section.cpp b/src/world/Section.cpp index 8f94ad7..a338e49 100644 --- a/src/world/Section.cpp +++ b/src/world/Section.cpp @@ -1,8 +1,11 @@ -#include "Section.hpp" +#include -Section::Section(byte *dataBlocks, size_t dataBlocksLength, byte *dataLight, byte *dataSky, byte bitsPerBlock, +Section::Section(Vector position, byte *dataBlocks, size_t dataBlocksLength, byte *dataLight, byte *dataSky, + byte bitsPerBlock, std::vector palette) { + worldPosition = position; + m_dataBlocksLen = dataBlocksLength; m_dataBlocks = new byte[m_dataBlocksLen]; std::copy(dataBlocks, dataBlocks + m_dataBlocksLen, m_dataBlocks); @@ -97,7 +100,7 @@ void Section::Parse() { } Section &Section::operator=(Section other) { - std::swap(*this,other); + std::swap(*this, other); return *this; } @@ -113,6 +116,7 @@ void swap(Section &a, Section &b) { } Section::Section(const Section &other) { + worldPosition = other.worldPosition; m_dataBlocksLen = other.m_dataBlocksLen; m_dataBlocks = new byte[m_dataBlocksLen]; std::copy(other.m_dataBlocks, other.m_dataBlocks + m_dataBlocksLen, m_dataBlocks); @@ -127,4 +131,8 @@ Section::Section(const Section &other) { m_palette = other.m_palette; m_bitsPerBlock = other.m_bitsPerBlock; -} \ No newline at end of file +} + +Vector Section::GetPosition() { + return worldPosition; +} diff --git a/src/world/Section.hpp b/src/world/Section.hpp deleted file mode 100644 index 657fc13..0000000 --- a/src/world/Section.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "Block.hpp" -#include "../utility/Vector.hpp" -#include "../utility/utility.h" - -const int SECTION_WIDTH = 16; -const int SECTION_LENGTH = 16; -const int SECTION_HEIGHT = 16; - -class Section { - std::vector m_palette; - byte *m_dataBlocks = nullptr; - size_t m_dataBlocksLen; - byte *m_dataLight = nullptr; - byte *m_dataSkyLight = nullptr; - byte m_bitsPerBlock = 0; - std::vector m_blocks; - std::condition_variable parseWaiter; - - Section(); - -public: - void Parse(); - - Section(byte *dataBlocks, size_t dataBlocksLength, byte *dataLight, byte *dataSky, byte bitsPerBlock, - std::vector palette); - - ~Section(); - - Block &GetBlock(Vector pos); - - Section &operator=(Section other); - - friend void swap(Section &a, Section& b); - - Section(const Section &other); - -}; \ No newline at end of file diff --git a/src/world/World.cpp b/src/world/World.cpp index 394598b..abcfebf 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -1,4 +1,4 @@ -#include "World.hpp" +#include void World::ParseChunkData(std::shared_ptr packet) { StreamBuffer chunkData(packet->Data.data(), packet->Data.size()); @@ -6,7 +6,7 @@ void World::ParseChunkData(std::shared_ptr packet) { for (int i = 0; i < 16; i++) { if (bitmask[i]) { Vector chunkPosition = Vector(packet->ChunkX, i, packet->ChunkZ); - Section section = ParseSection(&chunkData); + Section section = ParseSection(&chunkData, chunkPosition); auto it = sections.find(chunkPosition); if (it == sections.end()) { sections.insert(std::make_pair(chunkPosition, section)); @@ -19,7 +19,7 @@ void World::ParseChunkData(std::shared_ptr packet) { } } -Section World::ParseSection(StreamInput *data) { +Section World::ParseSection(StreamInput *data, Vector position) { unsigned char bitsPerBlock = data->ReadUByte(); int paletteLength = data->ReadVarInt(); std::vector palette; @@ -32,7 +32,7 @@ Section World::ParseSection(StreamInput *data) { std::vector skyLight; if (dimension == 0) skyLight = data->ReadByteArray(4096 / 2); - return Section(dataArray.data(), dataArray.size(), blockLight.data(), + return Section(position, dataArray.data(), dataArray.size(), blockLight.data(), (skyLight.size() > 0 ? skyLight.data() : nullptr), bitsPerBlock, palette); } diff --git a/src/world/World.hpp b/src/world/World.hpp deleted file mode 100644 index e315baf..0000000 --- a/src/world/World.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include "Block.hpp" -#include "Section.hpp" -#include "../network/Packet.hpp" -#include "Collision.hpp" - -class World { - //utility vars - World(const World &other); - - World &operator=(const World &other); - - //game vars - int dimension = 0; - - //game methods - Section ParseSection(StreamInput *data); - -public: - World(); - - ~World(); - - void ParseChunkData(std::shared_ptr packet); - - std::map sections; - - bool isPlayerCollides(double X, double Y, double Z); -}; \ No newline at end of file -- cgit v1.2.3