diff options
Diffstat (limited to 'src')
38 files changed, 381 insertions, 2559 deletions
diff --git a/src/Core.cpp b/src/Core.cpp deleted file mode 100644 index 3a89c07..0000000 --- a/src/Core.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "Core.hpp" -#include "NetworkClient.hpp" - -Core::Core() { - coreLoop = std::thread(&Core::ExecuteCoreLoop, this); - render = new Render(900, 480, "AltCraft"); -} - -Core::~Core() { - delete render; - coreLoop.join(); -} - -void Core::ExecuteRenderLoop() { - render->ExecuteRenderLoop(); -} - -void Core::ExecuteCoreLoop() { - - EventListener events; - events.RegisterHandler(EventType::ConnectionSuccessfull, [](EventData eventData) { - GlobalAppStateData data = {GlobalState::Loading}; - EventAgregator::PushEvent(EventType::GlobalAppState, EventData{data}); - }); - events.RegisterHandler(EventType::GlobalAppState, [this](EventData eventData) { - auto data = std::get<GlobalAppStateData>(eventData); - globalState = data.state; - }); - - while (globalState != GlobalState::Exiting) { - if (events.IsEventsQueueIsNotEmpty()) { - events.HandleEvent(); - } - } -} - -void Core::ExecuteNetworkLoop() { - NetworkClient *nc; - EventListener events; - bool isRunning = true; - events.RegisterHandler(EventType::ConnectToServer, [](EventData eventData) { - auto data = std::get<ConnectToServerData>(eventData); - try { - nc = new NetworkClient(data.address, data.port, "HelloOne", isRunning); - } catch (std::exception &e) { - GlobalAppStateData data{GlobalState::Exiting}; - EventAgregator::PushEvent(EventType::GlobalAppState, data); - } - }); - events.RegisterHandler(EventType::Disconnect, [nc](EventData eventData) { - delete nc; - nc = nullptr; - }); - - while (globalState != GlobalState::Exiting) { - - } - delete nc; -} diff --git a/src/Core.hpp b/src/Core.hpp deleted file mode 100644 index 3c2d8da..0000000 --- a/src/Core.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include <thread> -#include <memory> - -#include "Render.hpp" -#include "Event.hpp" - -class Core { - std::thread coreLoop; - std::thread networkLoop; - Render* render; - - GlobalState globalState = GlobalState::InitialLoading; - - void ExecuteCoreLoop(); - void ExecuteNetworkLoop(); -public: - Core(); - ~Core(); - - void ExecuteRenderLoop(); -};
\ No newline at end of file diff --git a/src/Event.cpp b/src/Event.cpp index ff16178..19c93f2 100644 --- a/src/Event.cpp +++ b/src/Event.cpp @@ -1,100 +1,107 @@ #include "Event.hpp" #include <easylogging++.h> -std::queue <Event> EventAgregator::eventsToHandle; +std::queue<Event> EventAgregator::eventsToHandle; std::mutex EventAgregator::queueMutex; bool EventAgregator::isStarted = false; -std::vector<EventListener*> EventAgregator::listeners; +std::vector<EventListener *> EventAgregator::listeners; std::mutex EventAgregator::listenersMutex; EventListener::EventListener() { - EventAgregator::RegisterListener(*this); + EventAgregator::RegisterListener(*this); } EventListener::~EventListener() { - EventAgregator::UnregisterListener(*this); + EventAgregator::UnregisterListener(*this); } void EventListener::PushEvent(Event event) { - eventsMutex.lock(); - events.push(event); - eventsMutex.unlock(); + eventsMutex.lock(); + handlersMutex.lock(); + if (handlers[event.type]) { + //LOG(ERROR) << "Listener notified about event " << int(event.type); + events.push(event); + } + handlersMutex.unlock(); + eventsMutex.unlock(); } bool EventListener::IsEventsQueueIsNotEmpty() { - eventsMutex.lock(); - bool value = !events.empty(); - eventsMutex.unlock(); - return value; + eventsMutex.lock(); + bool value = !events.empty(); + eventsMutex.unlock(); + return value; } void EventListener::RegisterHandler(EventType type, EventListener::HandlerFunc handler) { + handlersMutex.lock(); handlers[type] = handler; + handlersMutex.unlock(); } void EventListener::HandleEvent() { - eventsMutex.lock(); - if (events.empty()) { - eventsMutex.unlock(); - return; - } - Event event = events.front(); - events.pop(); - eventsMutex.unlock(); - auto function = handlers[event.type]; - function(event.data); + eventsMutex.lock(); + if (events.empty()) { + eventsMutex.unlock(); + return; + } + Event event = events.front(); + events.pop(); + eventsMutex.unlock(); + handlersMutex.lock(); + auto function = handlers[event.type]; + handlersMutex.unlock(); + function(event.data); } - void EventAgregator::RegisterListener(EventListener &listener) { - listenersMutex.lock(); - LOG(WARNING)<<"Registered handler "<<&listener; - listeners.push_back(&listener); - listenersMutex.unlock(); + listenersMutex.lock(); + LOG(WARNING) << "Registered handler " << &listener; + listeners.push_back(&listener); + listenersMutex.unlock(); } void EventAgregator::UnregisterListener(EventListener &listener) { - listenersMutex.lock(); - LOG(WARNING)<<"Unregistered handler "<<&listener; - listeners.erase(std::find(listeners.begin(), listeners.end(), &listener)); - listenersMutex.unlock(); + listenersMutex.lock(); + LOG(WARNING) << "Unregistered handler " << &listener; + listeners.erase(std::find(listeners.begin(), listeners.end(), &listener)); + listenersMutex.unlock(); } void EventAgregator::PushEvent(EventType type, EventData data) { - Event event; - event.type = type; - event.data = data; - eventsToHandle.push(event); - if (!isStarted) { - isStarted = true; - std::thread(&EventAgregator::EventHandlingLoop).detach(); - } + Event event; + event.type = type; + event.data = data; + eventsToHandle.push(event); + if (!isStarted) { + isStarted = true; + std::thread(&EventAgregator::EventHandlingLoop).detach(); + } } void EventAgregator::EventHandlingLoop() { - while (true) { - queueMutex.lock(); - if (!eventsToHandle.empty()) { - auto queue = eventsToHandle; - while (!eventsToHandle.empty()) - eventsToHandle.pop(); - queueMutex.unlock(); - - while (!queue.empty()) { - auto event = queue.front(); - listenersMutex.lock(); - for (auto& listener : listeners) { - LOG(ERROR)<<"Listener notified about event"; - listener->PushEvent(event); - } - listenersMutex.unlock(); - queue.pop(); - } - - queueMutex.lock(); - } - queueMutex.unlock(); - } + while (true) { + queueMutex.lock(); + if (!eventsToHandle.empty()) { + auto queue = eventsToHandle; + while (!eventsToHandle.empty()) + eventsToHandle.pop(); + queueMutex.unlock(); + + while (!queue.empty()) { + auto event = queue.front(); + listenersMutex.lock(); + for (auto &listener : listeners) { + listener->PushEvent(event); + } + listenersMutex.unlock(); + queue.pop(); + } + + queueMutex.lock(); + } + queueMutex.unlock(); + } } diff --git a/src/Event.hpp b/src/Event.hpp index 2d830a4..229da19 100644 --- a/src/Event.hpp +++ b/src/Event.hpp @@ -19,8 +19,10 @@ enum class EventType { ConnectionSuccessfull, GlobalAppState, Disconnect, - SendPacket, - ReceivePacket, + RequestNetworkClient, + RegisterNetworkClient, + PlayerConnected, + RemoveLoadingScreen, }; struct EchoData { @@ -36,8 +38,10 @@ struct ConnectToServerData { unsigned short port; }; -struct ConnectionSuccessfullData { +class NetworkClient; +struct ConnectionSuccessfullData { + NetworkClient *ptr; }; enum class GlobalState { @@ -65,8 +69,27 @@ struct ReceivePacketData { std::shared_ptr<Packet> packet; }; +struct RequestNetworkClientData { + +}; + +struct RegisterNetworkClientData { + NetworkClient *ptr; +}; + +class GameState; + +struct PlayerConnectedData { + GameState *ptr; +}; + +struct RemoveLoadingScreenData { + +}; + using EventData = std::variant<EchoData, ChunkChangedData, ConnectToServerData, ConnectionSuccessfullData, - GlobalAppStateData, DisconnectData, SendPacketData, ReceivePacketData>; + GlobalAppStateData, DisconnectData, SendPacketData, ReceivePacketData, RequestNetworkClientData, + RegisterNetworkClientData, PlayerConnectedData, RemoveLoadingScreenData>; struct Event { EventType type; @@ -80,10 +103,12 @@ class EventListener { std::map<EventType, HandlerFunc> handlers; //TODO: There must be more elegant solution than std::variant of all data - std::mutex eventsMutex; + std::mutex handlersMutex; std::queue<Event> events; + std::mutex eventsMutex; + void PushEvent(Event event); public: diff --git a/src/FSM.cpp b/src/FSM.cpp new file mode 100644 index 0000000..6614c58 --- /dev/null +++ b/src/FSM.cpp @@ -0,0 +1 @@ +#include "FSM.hpp" diff --git a/src/FSM.hpp b/src/FSM.hpp new file mode 100644 index 0000000..9570e26 --- /dev/null +++ b/src/FSM.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include <utility> +#include <functional> +#include <map> + +template<class T> +class FSM { + T previousState; + T &state; + std::map<Transaction, std::function<void()>> handlers; +public: + using Transaction = std::pair<T, T>; + + FSM(T &value) : state(value), previousState(value) {} + + ~FSM() = default; + + void Update() { + auto handler = handlers[Transaction{previousState, state}]; + if (handler) + handler(); + } + + void RegisterHandler(T state, std::function<void()> handler) { + handlers[Transaction{state, state}] = handler; + } + + void RegisterTransactionHandler(Transaction transaction, std::function<void()> handler) { + handlers[transaction] = handler; + } +};
\ No newline at end of file diff --git a/src/GameState.cpp b/src/GameState.cpp index 3ccff37..e9c2cef 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -1,6 +1,7 @@ #include "GameState.hpp" +#include "Event.hpp" -GameState::GameState(NetworkClient *Net, bool &quit) : nc(Net), isRunning(quit) { +GameState::GameState(NetworkClient *networkClient) : nc(networkClient) { 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); @@ -14,8 +15,10 @@ void GameState::Update(float deltaTime) { auto delta = clock.now() - timeOfPreviousSendedPacket; using namespace std::chrono_literals; if (delta >= 50ms) { - nc->SendPacket(std::make_shared<PacketPlayerPositionAndLookSB>(g_PlayerX, g_PlayerY, g_PlayerZ, g_PlayerYaw, - g_PlayerPitch, g_OnGround)); + auto packetToSend = std::make_shared<PacketPlayerPositionAndLookSB>(g_PlayerX, g_PlayerY, g_PlayerZ, + g_PlayerYaw, + g_PlayerPitch, g_OnGround); + nc->SendPacket(packetToSend); timeOfPreviousSendedPacket = clock.now(); } @@ -111,7 +114,7 @@ void GameState::Update(float deltaTime) { case DisconnectPlay: { auto packet = std::static_pointer_cast<PacketDisconnectPlay>(ptr); LOG(INFO) << "Disconnect reason: " << packet->Reason; - isRunning = false; + EventAgregator::PushEvent(EventType::GlobalAppState, GlobalAppStateData{GlobalState::Exiting}); break; } case EntityStatus: @@ -145,6 +148,7 @@ void GameState::Update(float deltaTime) { g_ReducedDebugInfo = packet->ReducedDebugInfo; LOG(INFO) << "Gamemode is " << g_Gamemode << ", Difficulty is " << (int) g_Difficulty << ", Level Type is " << g_LevelType; + EventAgregator::PushEvent(EventType::PlayerConnected, PlayerConnectedData{this}); break; } case Map: @@ -203,6 +207,11 @@ void GameState::Update(float deltaTime) { LOG(INFO) << "PlayerPos is " << g_PlayerX << ", " << g_PlayerY << ", " << g_PlayerZ << "\t\tAngle: " << g_PlayerYaw << "," << g_PlayerPitch; + if (!g_IsGameStarted) { + LOG(INFO) << "Game is started"; + EventAgregator::PushEvent(EventType::RemoveLoadingScreen, RemoveLoadingScreenData{}); + } + g_IsGameStarted = true; auto packetResponse = std::make_shared<PacketTeleportConfirm>(packet->TeleportId); @@ -342,7 +351,7 @@ void GameState::HandleRotation(double yaw, double pitch) { glm::mat4 GameState::GetViewMatrix() { auto pos = this->Position(); - pos.y+=1.62; + pos.y += 1.62; return glm::lookAt(pos, pos + this->Front, this->Up); } diff --git a/src/GameState.hpp b/src/GameState.hpp index 2ac7bc1..076c81b 100644 --- a/src/GameState.hpp +++ b/src/GameState.hpp @@ -11,7 +11,7 @@ class GameState { NetworkClient *nc; public: - GameState(NetworkClient *NetClient, bool &quit); + GameState(NetworkClient *networkClient); void Update(float deltaTime); @@ -38,7 +38,7 @@ public: //Everything other World world; - bool &isRunning; + //bool &isRunning; std::string g_PlayerUuid; std::string g_PlayerName; diff --git a/src/Network.cpp b/src/Network.cpp index dcdda10..6cd9baa 100644 --- a/src/Network.cpp +++ b/src/Network.cpp @@ -3,9 +3,17 @@ Network::Network(std::string address, unsigned short port) { try { socket = new Socket(address, port); + } catch (std::exception &e) { + LOG(WARNING) << "CONNECT FAULT"; + delete socket; + throw; + } + + try { stream = new StreamSocket(socket); } catch (std::exception &e) { - LOG(FATAL)<<e.what(); + LOG(WARNING) << "NOT STREAMED"; + LOG(FATAL) << e.what(); } } @@ -33,7 +41,7 @@ void Network::SendPacket(Packet &packet) { } std::shared_ptr<Packet> Network::ReceivePacketByPacketId(int packetId, ConnectionState state, StreamInput &stream) { - std::shared_ptr<Packet> packet(nullptr); + std::shared_ptr < Packet > packet(nullptr); switch (state) { case Handshaking: switch (packetId) { diff --git a/src/NetworkClient.cpp b/src/NetworkClient.cpp index 0b759e6..235251f 100644 --- a/src/NetworkClient.cpp +++ b/src/NetworkClient.cpp @@ -6,8 +6,8 @@ NetworkClient::NetworkClient(std::string address, unsigned short port, std::stri PacketHandshake handshake; handshake.protocolVersion = 335; - handshake.serverAddress = "127.0.0.1"; - handshake.serverPort = 25565; + handshake.serverAddress = address; + handshake.serverPort = port; handshake.nextState = 2; network.SendPacket(handshake); state = Login; @@ -24,8 +24,7 @@ NetworkClient::NetworkClient(std::string address, unsigned short port, std::stri state = Play; isActive = true; - std::thread thread(&NetworkClient::NetworkLoop, this); - std::swap(networkThread, thread); + networkThread = std::thread(&NetworkClient::NetworkLoop, this); } NetworkClient::~NetworkClient() { @@ -35,7 +34,7 @@ NetworkClient::~NetworkClient() { std::shared_ptr<Packet> NetworkClient::ReceivePacket() { if (toReceive.empty()) - return std::shared_ptr<Packet>(nullptr); + return std::shared_ptr < Packet > (nullptr); toReceiveMutex.lock(); auto ret = toReceive.front(); toReceive.pop(); @@ -57,7 +56,7 @@ void NetworkClient::NetworkLoop() { while (isActive) { toSendMutex.lock(); while (!toSend.empty()) { - if (toSend.front()!=nullptr) + if (toSend.front() != nullptr) network.SendPacket(*toSend.front()); toSend.pop(); } @@ -78,7 +77,7 @@ void NetworkClient::NetworkLoop() { using namespace std::chrono_literals; if (std::chrono::steady_clock::now() - timeOfLastKeepAlivePacket > 20s) { auto disconnectPacket = std::make_shared<PacketDisconnectPlay>(); - disconnectPacket->Reason = "Timeout"; + disconnectPacket->Reason = "Timeout: server not respond"; toReceiveMutex.lock(); toReceive.push(disconnectPacket); toReceiveMutex.unlock(); diff --git a/src/Render.cpp b/src/Render.cpp index ebfbc20..d45d5b6 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -64,7 +64,6 @@ void Render::RenderFrame() { glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - window->display(); } @@ -89,6 +88,8 @@ void Render::HandleEvents() { case sf::Keyboard::T: SetMouseCapture(!isMouseCaptured); break; + case sf::Keyboard::U: + EventAgregator::PushEvent(EventType::ConnectToServer, ConnectToServerData{"127.0.0.1", 25565}); default: break; } @@ -122,6 +123,21 @@ void Render::SetMouseCapture(bool IsCaptured) { } void Render::ExecuteRenderLoop() { + EventListener listener; + listener.RegisterHandler(EventType::ConnectionSuccessfull, [this](EventData eventData) { + auto data = std::get<ConnectionSuccessfullData>(eventData); + window->setTitle("Connected"); + }); + + listener.RegisterHandler(EventType::PlayerConnected, [this](EventData eventData) { + auto data = std::get<PlayerConnectedData>(eventData); + window->setTitle("Joined the game"); + }); + + listener.RegisterHandler(EventType::RemoveLoadingScreen, [this](EventData eventData) { + window->setTitle("Loaded"); + }); + using namespace std::chrono_literals; LoopExecutionTimeController timer(16ms); while (isRunning) { @@ -130,8 +146,10 @@ void Render::ExecuteRenderLoop() { glCheckError(); RenderFrame(); + while (listener.IsEventsQueueIsNotEmpty()) + listener.HandleEvent(); timer.Update(); } EventData data = GlobalAppStateData{GlobalState::Exiting}; - EventAgregator::PushEvent(EventType::GlobalAppState,data); + EventAgregator::PushEvent(EventType::GlobalAppState, data); } diff --git a/src/RendererWorld.hpp b/src/RendererWorld.hpp index 761bbde..83020aa 100644 --- a/src/RendererWorld.hpp +++ b/src/RendererWorld.hpp @@ -3,5 +3,10 @@ #include "RendererSection.hpp" class RendererWorld { + World* world; +public: + RendererWorld(World* ptr); + ~RendererWorld(); + };
\ No newline at end of file diff --git a/src/Socket.cpp b/src/Socket.cpp index 2bbf49a..519da2f 100644 --- a/src/Socket.cpp +++ b/src/Socket.cpp @@ -1,3 +1,4 @@ +#include <iostream> #include "Socket.hpp" Socket::Socket(std::string address, unsigned short port) { diff --git a/src/Thread.cpp b/src/Thread.cpp new file mode 100644 index 0000000..3ebc2c2 --- /dev/null +++ b/src/Thread.cpp @@ -0,0 +1 @@ +#include "Thread.hpp" diff --git a/src/Thread.hpp b/src/Thread.hpp new file mode 100644 index 0000000..ddc0dc5 --- /dev/null +++ b/src/Thread.hpp @@ -0,0 +1,7 @@ +#pragma once + +struct Thread { + Thread() = default; + virtual ~Thread() = default; + virtual void Execute() = 0; +};
\ No newline at end of file diff --git a/src/ThreadGame.cpp b/src/ThreadGame.cpp new file mode 100644 index 0000000..03c2c14 --- /dev/null +++ b/src/ThreadGame.cpp @@ -0,0 +1,35 @@ +#include "ThreadGame.hpp" + + +ThreadGame::ThreadGame() { + +} + +ThreadGame::~ThreadGame() { + +} + +void ThreadGame::Execute() { + + EventListener listener; + + listener.RegisterHandler(EventType::GlobalAppState, [this](EventData eventData) { + auto data = std::get<GlobalAppStateData>(eventData); + state = data.state; + }); + + listener.RegisterHandler(EventType::ConnectionSuccessfull, [this](EventData eventData) { + auto data = std::get<ConnectionSuccessfullData>(eventData); + gs = new GameState(data.ptr); + }); + + LoopExecutionTimeController timer(std::chrono::milliseconds(int(1.0f / 60.0f * 1000.0f))); + + while (state != GlobalState::Exiting) { + listener.HandleEvent(); + if (gs != nullptr) + gs->Update(timer.GetDeltaMs()); + timer.Update(); + } + delete gs; +} diff --git a/src/ThreadGame.hpp b/src/ThreadGame.hpp new file mode 100644 index 0000000..81d135f --- /dev/null +++ b/src/ThreadGame.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "Thread.hpp" +#include "GameState.hpp" +#include "Event.hpp" + +class ThreadGame: Thread { + GameState *gs = nullptr; + GlobalState state = GlobalState::InitialLoading; +public: + ThreadGame(); + ~ThreadGame(); + void Execute() override; +};
\ No newline at end of file diff --git a/src/ThreadNetwork.cpp b/src/ThreadNetwork.cpp new file mode 100644 index 0000000..b97a3f0 --- /dev/null +++ b/src/ThreadNetwork.cpp @@ -0,0 +1,60 @@ +#include "ThreadNetwork.hpp" + +ThreadNetwork::ThreadNetwork() { + +} + +ThreadNetwork::~ThreadNetwork() { + delete nc; +} + +void ThreadNetwork::Execute() { + bool isRunning; + EventListener listener; + + listener.RegisterHandler(EventType::GlobalAppState, [this](EventData eventData) { + auto data = std::get<GlobalAppStateData>(eventData); + state = data.state; + }); + + listener.RegisterHandler(EventType::ConnectToServer, [this, &isRunning](EventData eventData) { + auto data = std::get<ConnectToServerData>(eventData); + if (data.address == "" || data.port == 0) + LOG(FATAL) << "NOT VALID CONNECT-TO-SERVER EVENT"; + if (nc != nullptr) { + LOG(ERROR) << "Already connected"; + return; + } + + LOG(INFO) << "Connecting to server"; + try { + nc = new NetworkClient(data.address, data.port, "HelloOne", isRunning); + } catch (std::exception &e) { + LOG(WARNING) << "CONNECTION FAIL"; + LOG(FATAL) << "Can't connect to server: " << e.what(); + } + LOG(INFO) << "Connected to server"; + EventAgregator::PushEvent(EventType::ConnectionSuccessfull, ConnectionSuccessfullData{nc}); + }); + + listener.RegisterHandler(EventType::RequestNetworkClient, [this](EventData eventData) { + EventAgregator::PushEvent(EventType::RegisterNetworkClient, RegisterNetworkClientData{nc}); + }); + + /*listener.RegisterHandler(EventType::SendPacket, [this](EventData eventData) { + auto data = std::get<SendPacketData>(eventData); + auto packet = data.packet; + if (nc) + nc->SendPacket(packet); + else + LOG(ERROR) << "Send packet, while not connected to server"; + });*/ + + + while (state != GlobalState::Exiting) { + /*auto packet = nc ? nc->ReceivePacket() : nullptr; + if (packet != nullptr) + EventAgregator::PushEvent(EventType::ReceivePacket, ReceivePacketData{packet});*/ + listener.HandleEvent(); + } +}
\ No newline at end of file diff --git a/src/ThreadNetwork.hpp b/src/ThreadNetwork.hpp new file mode 100644 index 0000000..a0917cd --- /dev/null +++ b/src/ThreadNetwork.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "Thread.hpp" +#include "NetworkClient.hpp" +#include "Event.hpp" + +class ThreadNetwork : Thread { + NetworkClient *nc = nullptr; + GlobalState state; +public: + ThreadNetwork(); + ~ThreadNetwork(); + void Execute() override; +};
\ No newline at end of file diff --git a/src/ThreadRender.cpp b/src/ThreadRender.cpp new file mode 100644 index 0000000..540be52 --- /dev/null +++ b/src/ThreadRender.cpp @@ -0,0 +1,13 @@ +#include "ThreadRender.hpp" + +ThreadRender::ThreadRender() { + render = new Render(900, 480, "AltCraft"); +} + +ThreadRender::~ThreadRender() { + delete render; +} + +void ThreadRender::Execute() { + render->ExecuteRenderLoop(); +} diff --git a/src/ThreadRender.hpp b/src/ThreadRender.hpp new file mode 100644 index 0000000..4d9223f --- /dev/null +++ b/src/ThreadRender.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "Thread.hpp" +#include "Render.hpp" + +class ThreadRender : Thread { + Render *render; +public: + ThreadRender(); + ~ThreadRender(); + void Execute() override; +};
\ No newline at end of file diff --git a/src/core/AssetManager.cpp b/src/core/AssetManager.cpp deleted file mode 100644 index d263c4a..0000000 --- a/src/core/AssetManager.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include <AssetManager.hpp> - -namespace fs = std::experimental::filesystem; - -//const fs::path pathToAssets = "./assets/"; -//const fs::path pathToAssetsList = "./items.json"; -//const fs::path pathToTextureIndex = "./textures.json"; -const std::string pathToAssetsList = "./items.json"; -const std::string pathToTextureIndex = "./textures.json"; - -AssetManager::AssetManager() { - LoadIds(); - LoadTextureResources(); -} - -void AssetManager::LoadIds() { - std::ifstream in(pathToAssetsList); - nlohmann::json index; - in >> index; - for (auto &it:index) { - int id = it["type"].get<int>(); - int state = it["meta"].get<int>(); - std::string blockName = it["text_type"].get<std::string>(); - assetIds[blockName] = Block(id, state); - } - LOG(INFO) << "Loaded " << assetIds.size() << " ids"; -} - -AssetManager::~AssetManager() { - delete textureAtlas; -} - -//TODO: This function must be replaced with runtime texture atlas generating -void AssetManager::LoadTextureResources() { - std::ifstream in(pathToTextureIndex); - nlohmann::json index; - in >> index; - std::string filename = index["meta"]["image"].get<std::string>(); - float textureWidth = index["meta"]["size"]["w"].get<int>(); - float textureHeight = index["meta"]["size"]["h"].get<int>(); - for (auto &it:index["frames"]) { - auto frame = it["frame"]; - TextureCoordinates coord; - coord.x = frame["x"].get<int>() / textureWidth; - coord.y = frame["y"].get<int>() / textureHeight; - coord.w = frame["w"].get<int>() / textureWidth; - coord.h = frame["h"].get<int>() / textureHeight; - std::string assetName = it["filename"].get<std::string>(); - assetName.insert(0, "minecraft/textures/"); - assetName.erase(assetName.length() - 4); - assetTextures[assetName] = coord; - } - - textureAtlas = new Texture(filename); - LOG(INFO) << "Texture atlas id is " << textureAtlas->texture; -} - -TextureCoordinates AssetManager::GetTextureByAssetName(std::string AssetName) { - if (assetTextures.find(AssetName) != assetTextures.end()) - return assetTextures[AssetName]; - else - return TextureCoordinates{-1, -1, -1, -1}; -} - -std::string AssetManager::GetTextureAssetNameByBlockId(BlockTextureId block) { - //Block sides: 0 - bottom, 1 - top, 2 - north, 3 - south, 4 - west, 5 - east 6 - every side - const std::map<BlockTextureId, std::string> lookupTable = { - {BlockTextureId(0, 0), "minecraft/textures/blocks/air"}, - {BlockTextureId(1, 0), "minecraft/textures/blocks/stone"}, - {BlockTextureId(1, 1), "minecraft/textures/blocks/stone_granite"}, - - {BlockTextureId(2, 0, 0), "minecraft/textures/blocks/dirt"}, - {BlockTextureId(2, 0, 1), "minecraft/textures/blocks/grass_top"}, - {BlockTextureId(2, 0, 2), "minecraft/textures/blocks/grass_side"}, - {BlockTextureId(2, 0, 3), "minecraft/textures/blocks/grass_side"}, - {BlockTextureId(2, 0, 4), "minecraft/textures/blocks/grass_side"}, - {BlockTextureId(2, 0, 5), "minecraft/textures/blocks/grass_side"}, - - {BlockTextureId(3, 0), "minecraft/textures/blocks/dirt"}, - {BlockTextureId(4, 0), "minecraft/textures/blocks/cobblestone"}, - {BlockTextureId(5, 0), "minecraft/textures/blocks/planks"}, - - {BlockTextureId(7, 0), "minecraft/textures/blocks/bedrock"}, - - {BlockTextureId(17, 0, 0), "minecraft/textures/blocks/log_oak_top"}, - {BlockTextureId(17, 0, 1), "minecraft/textures/blocks/log_oak_top"}, - {BlockTextureId(17, 0, 2), "minecraft/textures/blocks/log_oak"}, - {BlockTextureId(17, 0, 3), "minecraft/textures/blocks/log_oak"}, - {BlockTextureId(17, 0, 4), "minecraft/textures/blocks/log_oak"}, - {BlockTextureId(17, 0, 5), "minecraft/textures/blocks/log_oak"}, - - {BlockTextureId(17, 1, 0), "minecraft/textures/blocks/log_spruce_top"}, - {BlockTextureId(17, 1, 1), "minecraft/textures/blocks/log_spruce_top"}, - {BlockTextureId(17, 1, 2), "minecraft/textures/blocks/log_spruce"}, - {BlockTextureId(17, 1, 3), "minecraft/textures/blocks/log_spruce"}, - {BlockTextureId(17, 1, 4), "minecraft/textures/blocks/log_spruce"}, - {BlockTextureId(17, 1, 5), "minecraft/textures/blocks/log_spruce"}, - - {BlockTextureId(17, 2, 0), "minecraft/textures/blocks/log_birch_top"}, - {BlockTextureId(17, 2, 1), "minecraft/textures/blocks/log_birch_top"}, - {BlockTextureId(17, 2, 2), "minecraft/textures/blocks/log_birch"}, - {BlockTextureId(17, 2, 3), "minecraft/textures/blocks/log_birch"}, - {BlockTextureId(17, 2, 4), "minecraft/textures/blocks/log_birch"}, - {BlockTextureId(17, 2, 5), "minecraft/textures/blocks/log_birch"}, - - {BlockTextureId(17, 3, 0), "minecraft/textures/blocks/log_jungle_top"}, - {BlockTextureId(17, 3, 1), "minecraft/textures/blocks/log_jungle_top"}, - {BlockTextureId(17, 3, 2), "minecraft/textures/blocks/log_jungle"}, - {BlockTextureId(17, 3, 3), "minecraft/textures/blocks/log_jungle"}, - {BlockTextureId(17, 3, 4), "minecraft/textures/blocks/log_jungle"}, - {BlockTextureId(17, 3, 5), "minecraft/textures/blocks/log_jungle"}, - - {BlockTextureId(18, 0), "minecraft/textures/blocks/leaves_oak"}, - {BlockTextureId(18, 1), "minecraft/textures/blocks/leaves_spruce"}, - {BlockTextureId(18, 2), "minecraft/textures/blocks/leaves_birch"}, - {BlockTextureId(18, 3), "minecraft/textures/blocks/leaves_jungle"}, - - {BlockTextureId(61, 0, 0), "minecraft/textures/blocks/furnace_side"}, - {BlockTextureId(61, 0, 1), "minecraft/textures/blocks/furnace_top"}, - {BlockTextureId(61, 0, 2), "minecraft/textures/blocks/furnace_front_off"}, - {BlockTextureId(61, 0, 3), "minecraft/textures/blocks/furnace_side"}, - {BlockTextureId(61, 0, 4), "minecraft/textures/blocks/furnace_side"}, - {BlockTextureId(61, 0, 5), "minecraft/textures/blocks/furnace_side"}, - - {BlockTextureId(62, 0, 0), "minecraft/textures/blocks/furnace_side"}, - {BlockTextureId(62, 0, 1), "minecraft/textures/blocks/furnace_top"}, - {BlockTextureId(62, 0, 2), "minecraft/textures/blocks/furnace_front_on"}, - {BlockTextureId(62, 0, 3), "minecraft/textures/blocks/furnace_side"}, - {BlockTextureId(62, 0, 4), "minecraft/textures/blocks/furnace_side"}, - {BlockTextureId(62, 0, 5), "minecraft/textures/blocks/furnace_side"}, - - - {BlockTextureId(31, 0), "minecraft/textures/blocks/deadbush"}, - {BlockTextureId(31, 1), "minecraft/textures/blocks/tallgrass"}, - {BlockTextureId(31, 2), "minecraft/textures/blocks/fern"}, - }; - auto ret = lookupTable.find(block); - if (ret == lookupTable.end()) - return ""; - else - return ret->second; -} - -GLuint AssetManager::GetTextureAtlas() { - return textureAtlas->texture; -} - -TextureCoordinates AssetManager::GetTextureByBlock(BlockTextureId block) { - std::string assetName = this->GetTextureAssetNameByBlockId(block); - return this->GetTextureByAssetName(assetName); -} - -const std::map<BlockTextureId, glm::vec4> &AssetManager::GetTextureAtlasIndexes() { - if (!textureAtlasIndexes.empty()) - return textureAtlasIndexes; - - LOG(INFO) << "Initializing texture atlas..."; - for (int id = 1; id < 128; id++) { - for (int state = 0; state < 16; state++) { - BlockTextureId blockTextureId(id, state, 6); - if (!this->GetTextureByBlock(blockTextureId) && - !this->GetTextureByBlock(BlockTextureId(id, state, 0))) { - continue; - } - if (this->GetTextureByBlock(blockTextureId)) { - for (int i = 0; i < 6; i++) { - TextureCoordinates tc = this->GetTextureByBlock(BlockTextureId(id, state, 6)); - textureAtlasIndexes[BlockTextureId(id, state, i)] = glm::vec4(tc.x, tc.y, tc.w, tc.h); - } - } else { - for (int i = 0; i < 6; i++) { - TextureCoordinates tc = this->GetTextureByBlock(BlockTextureId(id, state, i)); - textureAtlasIndexes[BlockTextureId(id, state, i)] = glm::vec4(tc.x, tc.y, tc.w, tc.h); - } - } - } - } - LOG(INFO) << "Created " << textureAtlasIndexes.size() << " texture indexes"; - - return textureAtlasIndexes; -} diff --git a/src/core/Core.cpp b/src/core/Core.cpp deleted file mode 100644 index dcfa890..0000000 --- a/src/core/Core.cpp +++ /dev/null @@ -1,313 +0,0 @@ -#include "Core.hpp" - -Core::Core() { - LOG(INFO) << "Core initializing..."; - InitSfml(900, 450, "AltCraft"); - glCheckError(); - InitGlew(); - glCheckError(); - client = new NetworkClient("127.0.0.1", 25565, "HelloOne", isRunning); - gameState = new GameState(client, isRunning); - std::thread loop = std::thread(&Core::UpdateGameState, this); - std::swap(loop, gameStateLoopThread); - assetManager = new AssetManager; - PrepareToRendering(); - LOG(INFO) << "Core is initialized"; - glCheckError(); -} - -Core::~Core() { - LOG(INFO) << "Core stopping..."; - gameStateLoopThread.join(); - delete shader; - delete gameState; - delete client; - delete assetManager; - delete window; - LOG(INFO) << "Core is stopped"; -} - -void Core::Exec() { - LOG(INFO) << "Main loop is executing!"; - isRunning = true; - while (isRunning) { - static sf::Clock clock, clock1; - deltaTime = clock.getElapsedTime().asSeconds(); - absTime = clock1.getElapsedTime().asSeconds(); - clock.restart(); - - static bool alreadyDone = false; - if (gameState->g_IsGameStarted && !alreadyDone) { - alreadyDone = true; - UpdateChunksToRender(); - } - - std::ostringstream toWindow; - auto camPos = gameState->Position(); - auto velPos = glm::vec3(gameState->g_PlayerVelocityX, gameState->g_PlayerVelocityY, - gameState->g_PlayerVelocityZ); - toWindow << std::setprecision(2) << std::fixed; - toWindow << "Pos: " << camPos.x << ", " << camPos.y << ", " << camPos.z << "; "; - toWindow << "Health: " << gameState->g_PlayerHealth << "; "; - //toWindow << "OG: " << gameState->g_OnGround << "; "; - toWindow << "Vel: " << velPos.x << ", " << velPos.y << ", " << velPos.z << "; "; - toWindow << "FPS: " << (1.0f / deltaTime) << " "; - toWindow << " (" << deltaTime * 1000 << "ms); "; - toWindow << "Tickrate: " << tickRate << " (" << (1.0 / tickRate * 1000) << "ms); "; - window->setTitle(toWindow.str()); - - HandleEvents(); - if (isMouseCaptured) HandleMouseCapture(); - glCheckError(); - - RenderFrame(); - - } -} - -void Core::RenderFrame() { - glClearColor(0.2f, 0.3f, 0.3f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - switch (currentState) { - case MainMenu: - //RenderGui(MenuScreen); - break; - case Loading: - //RenderGui(LoadingScreen); - break; - case Playing: - RenderWorld(); - //RenderGui(HUD); - break; - case PauseMenu: - RenderWorld(); - //RenderGui(PauseGui); - break; - } - - window->display(); -} - -void Core::InitSfml(unsigned int WinWidth, unsigned int WinHeight, std::string WinTitle) { - LOG(INFO) << "Creating window: " << WinWidth << "x" << WinHeight << " \"" << WinTitle << "\""; - sf::ContextSettings contextSetting; - contextSetting.majorVersion = 3; - contextSetting.minorVersion = 3; - contextSetting.attributeFlags = contextSetting.Core; - contextSetting.depthBits = 24; - window = new sf::Window(sf::VideoMode(WinWidth, WinHeight), WinTitle, sf::Style::Default, contextSetting); - glCheckError(); - window->setVerticalSyncEnabled(true); - //window->setPosition(sf::Vector2i(sf::VideoMode::getDesktopMode().width / 2, sf::VideoMode::getDesktopMode().height / 2)); - window->setPosition(sf::Vector2i(sf::VideoMode::getDesktopMode().width / 2 - window->getSize().x / 2, - sf::VideoMode::getDesktopMode().height / 2 - window->getSize().y / 2)); - - SetMouseCapture(false); -} - -void Core::InitGlew() { - LOG(INFO) << "Initializing GLEW"; - glewExperimental = GL_TRUE; - GLenum glewStatus = glewInit(); - glCheckError(); - if (glewStatus != GLEW_OK) { - LOG(FATAL) << "Failed to initialize GLEW: " << glewGetErrorString(glewStatus); - } - glViewport(0, 0, width(), height()); - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - glFrontFace(GL_CCW); - //glEnable(GL_BLEND); - //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glCheckError(); -} - -unsigned int Core::width() { - return window->getSize().x; -} - -unsigned int Core::height() { - return window->getSize().y; -} - -void Core::HandleEvents() { - sf::Event event; - while (window->pollEvent(event)) { - switch (event.type) { - case sf::Event::Closed: - LOG(INFO) << "Received close event by window closing"; - isRunning = false; - break; - case sf::Event::Resized: - glViewport(0, 0, width(), height()); - break; - case sf::Event::KeyPressed: - if (!window->hasFocus()) break; - switch (event.key.code) { - case sf::Keyboard::Escape: - LOG(INFO) << "Received close event by esc"; - isRunning = false; - break; - case sf::Keyboard::T: - SetMouseCapture(!isMouseCaptured); - break; - case sf::Keyboard::L: - ChunkDistance++; - LOG(INFO) << "Increased render distance: " << ChunkDistance; - break; - case sf::Keyboard::K: - if (ChunkDistance > 1) { - ChunkDistance--; - LOG(INFO) << "Decreased render distance: " << ChunkDistance; - } - break; - default: - break; - } - /*case sf::Event::MouseWheelScrolled: - if (!window->hasFocus()) - break; - camera.ProcessMouseScroll(event.mouseWheelScroll.delta); - break;*/ - default: - break; - } - } - if (window->hasFocus()) { - if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) gameState->HandleMovement(GameState::FORWARD, deltaTime); - if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) gameState->HandleMovement(GameState::BACKWARD, deltaTime); - if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) gameState->HandleMovement(GameState::LEFT, deltaTime); - if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) gameState->HandleMovement(GameState::RIGHT, deltaTime); - if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) gameState->HandleMovement(GameState::JUMP, deltaTime); - UpdateChunksToRender(); - } -} - -void Core::HandleMouseCapture() { - sf::Vector2i mousePos = sf::Mouse::getPosition(*window); - sf::Vector2i center = sf::Vector2i(window->getSize().x / 2, window->getSize().y / 2); - sf::Mouse::setPosition(center, *window); - mouseXDelta = (mousePos - center).x, mouseYDelta = (center - mousePos).y; - const float Sensetivity = 0.7f; - gameState->HandleRotation(mouseXDelta * Sensetivity, mouseYDelta * Sensetivity); - //camera.ProcessMouseMovement(mouseXDelta, mouseYDelta); -} - -void Core::RenderWorld() { - shader->Use(); - glCheckError(); - - GLint projectionLoc = glGetUniformLocation(shader->Program, "projection"); - GLint viewLoc = glGetUniformLocation(shader->Program, "view"); - GLint timeLoc = glGetUniformLocation(shader->Program, "time"); - glm::mat4 projection = glm::perspective(45.0f, (float) width() / (float) height(), 0.1f, 10000000.0f); - glm::mat4 view = gameState->GetViewMatrix(); - glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection)); - glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); - glUniform1f(timeLoc, absTime); - glUniform2f(glGetUniformLocation(shader->Program, "windowSize"), width(), height()); - - glCheckError(); - - for (auto &render : toRender) { - Section §ion = *availableChunks.find(render)->second.GetSection(); - - std::vector<Vector> sectionCorners = { - Vector(0, 0, 0), - Vector(0, 0, 16), - Vector(0, 16, 0), - Vector(0, 16, 16), - Vector(16, 0, 0), - Vector(16, 0, 16), - Vector(16, 16, 0), - Vector(16, 16, 16), - }; - bool isBreak = true; - for (auto &it:sectionCorners) { - glm::mat4 vp = projection * view; - 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) { - isBreak = false; - break; - } - } - if (isBreak && glm::length(gameState->Position() - - glm::vec3(section.GetPosition().GetX() * 16, - section.GetPosition().GetY() * 16, - section.GetPosition().GetZ() * 16)) > 30.0f) { - continue; - } - availableChunks.find(render)->second.Render(renderState); - } - glCheckError(); -} - -void Core::SetMouseCapture(bool IsCaptured) { - window->setMouseCursorVisible(!isMouseCaptured); - sf::Mouse::setPosition(sf::Vector2i(window->getSize().x / 2, window->getSize().y / 2), *window); - isMouseCaptured = IsCaptured; - window->setMouseCursorVisible(!IsCaptured); -} - -void Core::PrepareToRendering() { - shader = new Shader("./shaders/face.vs", "./shaders/face.fs"); - shader->Use(); - - //TextureAtlas texture - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, assetManager->GetTextureAtlas()); - glUniform1i(glGetUniformLocation(shader->Program, "textureAtlas"), 0); -} - -void Core::UpdateChunksToRender() { - Vector playerChunk = Vector(floor(gameState->g_PlayerX / 16.0f), 0, floor(gameState->g_PlayerZ / 16.0f)); - static Vector previousPlayerChunk = playerChunk; - static bool firstTime = true; - static int previousRenderDistance = ChunkDistance; - if (previousPlayerChunk == playerChunk && !firstTime && ChunkDistance == previousRenderDistance) { - return; - } - previousPlayerChunk = playerChunk; - previousRenderDistance = ChunkDistance; - toRender.clear(); - for (auto &it:gameState->world.GetSectionsList()) { - Vector chunkPosition = it; - chunkPosition.SetY(0); - Vector delta = chunkPosition - playerChunk; - if (delta.GetMagnitude() > ChunkDistance) continue; - toRender.push_back(it); - } - for (auto &it:toRender) { - if (availableChunks.find(it) == availableChunks.end()) { - auto pair = std::make_pair(it, RenderSection(&gameState->world, it)); - pair.second.UpdateState(assetManager->GetTextureAtlasIndexes()); - availableChunks.insert(pair); - } else { - //availableChunks.find(it)->second.UpdateState(); - } - } - if (firstTime) LOG(INFO) << "Chunks to render: " << toRender.size() << " of " << availableChunks.size(); - firstTime = false; -} - -void Core::UpdateGameState() { - el::Helpers::setThreadName("Game"); - LOG(INFO) << "GameState thread is started"; - sf::Clock delta; - while (isRunning) { - float deltaTime = delta.getElapsedTime().asSeconds(); - delta.restart(); - gameState->Update(deltaTime); - const double targetDelta = 1 / 60.0; - std::chrono::duration<double, std::ratio<1, 1>> timeToSleep(targetDelta - delta.getElapsedTime().asSeconds()); - std::this_thread::sleep_for(timeToSleep); - tickRate = 1 / delta.getElapsedTime().asSeconds(); - } - LOG(INFO) << "GameState thread is stopped"; -}
\ No newline at end of file diff --git a/src/graphics/Gui.cpp b/src/graphics/Gui.cpp deleted file mode 100644 index bbf7cf2..0000000 --- a/src/graphics/Gui.cpp +++ /dev/null @@ -1 +0,0 @@ -#include <graphics/Gui.hpp>
\ No newline at end of file diff --git a/src/graphics/RenderSection.cpp b/src/graphics/RenderSection.cpp deleted file mode 100644 index b07759a..0000000 --- a/src/graphics/RenderSection.cpp +++ /dev/null @@ -1,338 +0,0 @@ -#include <graphics/RenderSection.hpp> - -const GLfloat vertices[] = { - 0, 0, 0, - 1, 0, 1, - 1, 0, 0, - - 0, 0, 0, - 0, 0, 1, - 1, 0, 1, -}; - -const GLfloat uv_coords[] = { - 0.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - - 0.0f, 0.0f, - 1.0f, 0.0f, - 1.0f, 1.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<GLuint, int> RenderSection::refCounterVbo; -std::map<GLuint, int> 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, &VboTextures); - if (refCounterVbo.find(VboTextures) == refCounterVbo.end()) - refCounterVbo[VboTextures] = 0; - refCounterVbo[VboTextures]++; - - glGenBuffers(1, &VboModels); - if (refCounterVbo.find(VboModels) == refCounterVbo.end()) - refCounterVbo[VboModels] = 0; - refCounterVbo[VboModels]++; - - glGenBuffers(1, &VboColors); - if (refCounterVbo.find(VboColors) == refCounterVbo.end()) - refCounterVbo[VboColors] = 0; - refCounterVbo[VboColors]++; - - glGenVertexArrays(1, &Vao); - if (refCounterVao.find(Vao) == refCounterVao.end()) - refCounterVao[Vao] = 0; - refCounterVao[Vao]++; - - glBindVertexArray(Vao); - { - //Cube vertices - GLuint VertAttribPos = 0; - glBindBuffer(GL_ARRAY_BUFFER, VboVertices); - glVertexAttribPointer(VertAttribPos, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr); - glEnableVertexAttribArray(VertAttribPos); - - //Cube UVs - GLuint UvAttribPos = 2; - glBindBuffer(GL_ARRAY_BUFFER, VboUvs); - glVertexAttribPointer(UvAttribPos, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), nullptr); - glEnableVertexAttribArray(UvAttribPos); - - //Textures - GLuint textureAttribPos = 7; - glBindBuffer(GL_ARRAY_BUFFER, VboTextures); - glVertexAttribPointer(textureAttribPos, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr); - glEnableVertexAttribArray(textureAttribPos); - glVertexAttribDivisor(textureAttribPos, 1); - glCheckError(); - - //Blocks models - GLuint matAttribPos = 8; - size_t sizeOfMat4 = 4 * 4 * sizeof(GLfloat); - glBindBuffer(GL_ARRAY_BUFFER, VboModels); - glVertexAttribPointer(matAttribPos + 0, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, nullptr); - glVertexAttribPointer(matAttribPos + 1, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *) (1 * 4 * sizeof(GLfloat))); - glVertexAttribPointer(matAttribPos + 2, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *) (2 * 4 * sizeof(GLfloat))); - glVertexAttribPointer(matAttribPos + 3, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *) (3 * 4 * sizeof(GLfloat))); - glEnableVertexAttribArray(matAttribPos + 0); - glEnableVertexAttribArray(matAttribPos + 1); - glEnableVertexAttribArray(matAttribPos + 2); - glEnableVertexAttribArray(matAttribPos + 3); - glVertexAttribDivisor(matAttribPos + 0, 1); - glVertexAttribDivisor(matAttribPos + 1, 1); - glVertexAttribDivisor(matAttribPos + 2, 1); - glVertexAttribDivisor(matAttribPos + 3, 1); - - //Color - GLuint colorAttribPos = 12; - glBindBuffer(GL_ARRAY_BUFFER, VboColors); - glVertexAttribPointer(colorAttribPos, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr); - glEnableVertexAttribArray(colorAttribPos); - glVertexAttribDivisor(colorAttribPos, 1); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - } - glBindVertexArray(0); - glCheckError(); -} - -RenderSection::~RenderSection() { - refCounterVbo[VboTextures]--; - refCounterVbo[VboModels]--; - refCounterVbo[VboColors]--; - refCounterVao[Vao]--; - if (refCounterVbo[VboTextures] <= 0) - glDeleteBuffers(1, &VboTextures); - if (refCounterVbo[VboModels] <= 0) - glDeleteBuffers(1, &VboTextures); - if (refCounterVbo[VboColors] <= 0) - glDeleteBuffers(1, &VboColors); - - if (refCounterVao[Vao] <= 0) - glDeleteVertexArrays(1, &Vao); -} - -void RenderSection::UpdateState(const std::map<BlockTextureId, glm::vec4> &textureAtlas) { - Section §ion = world->GetSection(sectionPosition); - std::vector<glm::mat4> models; - std::vector<glm::vec4> textures; - std::vector<glm::vec3> colors; - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - Vector blockPos = Vector(x, y, z) + (sectionPosition * 16); - Block &block = world->GetBlock(blockPos); - if (block.id == 0) - continue; - - auto checkBlockVisibility = [&](Vector block) -> bool { - return section.GetBlock(block).id == 0 || - section.GetBlock(block).id == 31 || - section.GetBlock(block).id == 18; - }; - - unsigned char isVisible = 0; - if (x == 0 || x == 15 || y == 0 || y == 15 || z == 0 || z == 15) { - isVisible = 0b1111'1111; //All faces is visible - } else { - isVisible |= checkBlockVisibility(Vector(x - 1, y, z)) << 0; - isVisible |= checkBlockVisibility(Vector(x + 1, y, z)) << 1; - isVisible |= checkBlockVisibility(Vector(x, y + 1, z)) << 2; - isVisible |= checkBlockVisibility(Vector(x, y - 1, z)) << 3; - isVisible |= checkBlockVisibility(Vector(x, y, z - 1)) << 4; - isVisible |= checkBlockVisibility(Vector(x, y, z + 1)) << 5; - } - - if (isVisible == 0x00) - continue; - - glm::mat4 transform; - transform = glm::translate(transform, glm::vec3(sectionPosition.GetX() * 16, - sectionPosition.GetY() * 16, - sectionPosition.GetZ() * 16)); - transform = glm::translate(transform, glm::vec3(x, y, z)); - glm::vec3 biomeColor(0.275, 0.63, 0.1); - glm::vec3 color(0.0f, 0.0f, 0.0f); - if (block.id == 31 || block.id == 18) - color = biomeColor; - - if (block.id == 31) { //X-cross like blocks rendering - auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 2)); - for (int i = 0; i < 4; i++) { - textures.push_back(texture->second); - colors.push_back(color); - } - glm::mat4 faceTransform = glm::translate(transform, glm::vec3(0.15f, 0, 0.15f)); - faceTransform = glm::scale(faceTransform, glm::vec3(1.0f, 0.9f, 1.0f)); - faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0, 0.0f, 1.0f)); - faceTransform = glm::rotate(faceTransform, glm::radians(45.0f), glm::vec3(1.0f, 0.0f, 0)); - for (int i = 0; i < 4; i++) { - models.push_back(faceTransform); - faceTransform = glm::translate(faceTransform, glm::vec3(0.0f, 0.0f, 0.5f)); - faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f)); - faceTransform = glm::translate(faceTransform, glm::vec3(0.0f, 0.0f, -0.5f)); - } - continue; - } - - if (isVisible >> 0 & 0x1) { //east side of block (X+) - glm::mat4 faceTransform = glm::translate(transform, glm::vec3(0, 0, 0)); - faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0, 0.0f, 1.0f)); - models.push_back(faceTransform); - auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 2)); - if (texture != textureAtlas.end()) - textures.push_back(texture->second); - else - textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, - 0.0078125, 0.00442477876106194690)); //Fallback TNT texture - colors.push_back(color); - } - if (isVisible >> 1 & 0x1) { //west side X- - glm::mat4 faceTransform = glm::translate(transform, glm::vec3(1, 0, 0)); - faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0, 0.0f, 1.0f)); - faceTransform = glm::rotate(faceTransform, glm::radians(180.0f), glm::vec3(1.0f, 0.0f, 0.0f)); - faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1)); - models.push_back(faceTransform); - auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 3)); - if (texture != textureAtlas.end()) - textures.push_back(texture->second); - else - textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, - 0.0078125, 0.00442477876106194690)); //Fallback TNT texture - colors.push_back(color); - } - if (isVisible >> 2 & 0x1) { //Top side Y+ - glm::mat4 faceTransform = glm::translate(transform, glm::vec3(0, 1, 0)); - models.push_back(faceTransform); - auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 1)); - if (texture != textureAtlas.end()) - textures.push_back(texture->second); - else - textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, - 0.0078125, 0.00442477876106194690)); //Fallback TNT texture - if (block.id != 2) - colors.push_back(color); - else - colors.push_back(biomeColor); - } - if (isVisible >> 3 & 0x1) { //Bottom side Y- - glm::mat4 faceTransform = glm::translate(transform, glm::vec3(0, 0, 0)); - faceTransform = glm::rotate(faceTransform, glm::radians(180.0f), glm::vec3(1.0f, 0, 0)); - faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1)); - models.push_back(faceTransform); - auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 0)); - if (texture != textureAtlas.end()) - textures.push_back(texture->second); - else - textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, - 0.0078125, 0.00442477876106194690)); //Fallback TNT texture - colors.push_back(color); - } - if (isVisible >> 4 & 0x1) { //south side Z+ - glm::mat4 faceTransform = glm::translate(transform, glm::vec3(1, 0, 0)); - faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(-1.0f, 0.0f, 0.0f)); - faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0.0f, -1.0f, 0.0f)); - models.push_back(faceTransform); - auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 3)); - if (texture != textureAtlas.end()) - textures.push_back(texture->second); - else - textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, - 0.0078125, 0.00442477876106194690)); //Fallback TNT texture - colors.push_back(color); - } - if (isVisible >> 5 & 0x1) { //north side Z- - glm::mat4 faceTransform = glm::translate(transform, glm::vec3(0, 0, 1)); - faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(-1.0f, 0.0f, 0.0f)); - faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0.0f, -1.0f, 0.0f)); - faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1)); - faceTransform = glm::rotate(faceTransform, glm::radians(180.0f), glm::vec3(1, 0, 0.0f)); - faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1.0f)); - models.push_back(faceTransform); - auto texture = textureAtlas.find(BlockTextureId(block.id, block.state, 4)); - if (texture != textureAtlas.end()) - textures.push_back(texture->second); - else - textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, - 0.0078125, 0.00442477876106194690)); //Fallback TNT texture - colors.push_back(color); - } - } - } - } - - glBindBuffer(GL_ARRAY_BUFFER, VboTextures); - glBufferData(GL_ARRAY_BUFFER, textures.size() * sizeof(glm::vec4), textures.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, VboColors); - glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(glm::vec3), colors.data(), GL_DYNAMIC_DRAW); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glCheckError(); - - numOfFaces = textures.size(); -} - -void RenderSection::Render(RenderState &state) { - state.SetActiveVao(Vao); - glDrawArraysInstanced(GL_TRIANGLES, 0, 6, numOfFaces); - glCheckError(); -} - -Section *RenderSection::GetSection() { - return &world->GetSection(sectionPosition); -} - -RenderSection::RenderSection(const RenderSection &other) { - this->world = other.world; - this->VboModels = other.VboModels; - this->VboTextures = other.VboTextures; - this->VboColors = other.VboColors; - this->sectionPosition = other.sectionPosition; - this->Vao = other.Vao; - this->numOfFaces = other.numOfFaces; - - refCounterVbo[VboTextures]++; - refCounterVbo[VboModels]++; - refCounterVbo[VboColors]++; - refCounterVao[Vao]++; -} diff --git a/src/graphics/Shader.cpp b/src/graphics/Shader.cpp deleted file mode 100644 index 3d2efb8..0000000 --- a/src/graphics/Shader.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include <graphics/Shader.hpp> - -Shader::Shader(const GLchar *vertexPath, const GLchar *fragmentPath, const GLchar *geometryPath) { - vertex = vertexPath; - fragment = fragmentPath; - // 1. Получаем исходный код шейдера из filePath - std::string vertexCode; - std::string fragmentCode; - std::string geometryCode; - std::ifstream vShaderFile; - std::ifstream fShaderFile; - std::ifstream gShaderFile; - // Удостоверимся, что ifstream объекты могут выкидывать исключения - vShaderFile.exceptions(std::ifstream::failbit); - fShaderFile.exceptions(std::ifstream::failbit); - gShaderFile.exceptions(std::ifstream::failbit); - try { - // Открываем файлы - vShaderFile.open(vertexPath); - fShaderFile.open(fragmentPath); - if (geometryPath != nullptr) - gShaderFile.open(geometryPath); - std::stringstream vShaderStream, fShaderStream, gShaderStream; - // Считываем данные в потоки - vShaderStream << vShaderFile.rdbuf(); - fShaderStream << fShaderFile.rdbuf(); - if (geometryPath != nullptr) - gShaderStream << gShaderFile.rdbuf(); - // Закрываем файлы - vShaderFile.close(); - fShaderFile.close(); - if (geometryPath != nullptr) - gShaderFile.close(); - // Преобразовываем потоки в массив GLchar - vertexCode = vShaderStream.str(); - fragmentCode = fShaderStream.str(); - if (geometryPath != nullptr) - geometryCode = gShaderStream.str(); - } - catch (std::ifstream::failure e) { - LOG(ERROR) << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ"; - } - const GLchar *vShaderCode = vertexCode.c_str(); - const GLchar *fShaderCode = fragmentCode.c_str(); - const GLchar *gShaderCode = geometryCode.c_str(); - - // 2. Сборка шейдеров - GLuint vertex, fragment, geometry; - GLint success; - GLchar infoLog[512]; - - // Вершинный шейдер - vertex = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertex, 1, &vShaderCode, NULL); - glCompileShader(vertex); - // Если есть ошибки - вывести их - glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); - if (!success) { - glGetShaderInfoLog(vertex, 512, NULL, infoLog); - LOG(ERROR) << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog; - }; - - // Вершинный шейдер - fragment = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragment, 1, &fShaderCode, NULL); - glCompileShader(fragment); - // Если есть ошибки - вывести их - glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); - if (!success) { - glGetShaderInfoLog(fragment, 512, NULL, infoLog); - LOG(ERROR) << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog; - }; - - if (geometryPath != nullptr) { - geometry = glCreateShader(GL_GEOMETRY_SHADER); - glShaderSource(geometry, 1, &gShaderCode, NULL); - glCompileShader(geometry); - // Если есть ошибки - вывести их - glGetShaderiv(geometry, GL_COMPILE_STATUS, &success); - if (!success) { - glGetShaderInfoLog(geometry, 512, NULL, infoLog); - LOG(ERROR) << "ERROR::SHADER::GEOMETRY::COMPILATION_FAILED\n" << infoLog; - }; - } - - // Шейдерная программа - this->Program = glCreateProgram(); - glAttachShader(this->Program, vertex); - glAttachShader(this->Program, fragment); - if (geometryPath != nullptr) - glAttachShader(this->Program, geometry); - glLinkProgram(this->Program); - //Если есть ошибки - вывести их - glGetProgramiv(this->Program, GL_LINK_STATUS, &success); - if (!success) { - glGetProgramInfoLog(this->Program, 512, NULL, infoLog); - LOG(FATAL) << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog; - } - - // Удаляем шейдеры, поскольку они уже в программу и нам больше не нужны. - glDeleteShader(vertex); - glDeleteShader(fragment); -} - -void Shader::Use() { - glUseProgram(this->Program); -} - -void Shader::Reload() { - const GLchar *vertexPath = vertex; - const GLchar *fragmentPath = fragment; - this->~Shader(); - new(this) Shader(vertexPath, fragmentPath); - LOG(INFO) << "Shader is realoded!"; -} diff --git a/src/graphics/Texture.cpp b/src/graphics/Texture.cpp deleted file mode 100644 index e5e2bba..0000000 --- a/src/graphics/Texture.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include <graphics/Texture.hpp> - -Texture::Texture(std::string filename, GLenum textureWrapping, GLenum textureFiltering) { - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - - //Texture options - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, textureWrapping); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, textureWrapping); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, textureFiltering); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - //Image load - sf::Image image; - if (!image.loadFromFile(filename)) { - LOG(ERROR) << "Can't open image " << filename; - throw 201; - } - if (image.getPixelsPtr() == nullptr) { - LOG(ERROR) << "Image data is corrupted!"; - throw 202; - } - image.flipVertically(); - - - //Creating texture - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getSize().x, image.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, - (GLvoid *) image.getPixelsPtr()); - glGenerateMipmap(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, 0); - -} - -Texture::~Texture() { - glDeleteTextures(1, &texture); -} diff --git a/src/graphics/Widget.cpp b/src/graphics/Widget.cpp deleted file mode 100644 index e53bc87..0000000 --- a/src/graphics/Widget.cpp +++ /dev/null @@ -1 +0,0 @@ -#include <graphics/Widget.hpp>
\ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 7bc0fb6..7ff88e0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,36 +1,46 @@ -#include "Core.hpp" #include "Event.hpp" #include "Utility.hpp" +#include "ThreadGame.hpp" +#include "ThreadRender.hpp" +#include "ThreadNetwork.hpp" const char *getTimeSinceProgramStart(void) { - static auto initialTime = std::chrono::steady_clock().now(); - auto now = std::chrono::steady_clock().now(); - std::chrono::duration<double> seconds = now-initialTime; - static char buffer[30]; - sprintf(buffer, "%.2f", seconds.count()); - return buffer; + static auto initialTime = std::chrono::steady_clock().now(); + auto now = std::chrono::steady_clock().now(); + std::chrono::duration<double> seconds = now - initialTime; + static char buffer[30]; + sprintf(buffer, "%.2f", seconds.count()); + return buffer; } INITIALIZE_EASYLOGGINGPP int main() { - el::Configurations loggerConfiguration; - el::Helpers::installCustomFormatSpecifier( - el::CustomFormatSpecifier("%startTime", std::bind(getTimeSinceProgramStart))); - std::string format = "[%startTime][%level][%thread][%fbase]: %msg"; - loggerConfiguration.set(el::Level::Info, el::ConfigurationType::Format, format); - loggerConfiguration.set(el::Level::Error, el::ConfigurationType::Format, format); - loggerConfiguration.set(el::Level::Fatal, el::ConfigurationType::Format, format); - loggerConfiguration.set(el::Level::Warning, el::ConfigurationType::Format, format); - el::Helpers::setThreadName("Render"); - el::Loggers::reconfigureAllLoggers(loggerConfiguration); - el::Loggers::addFlag(el::LoggingFlag::ColoredTerminalOutput); - LOG(INFO) << "Logger is configured"; - - LOG(WARNING)<<"Sizeof EventData is "<<sizeof(EventData); - - Core core; - core.ExecuteRenderLoop(); - - return 0; + el::Configurations loggerConfiguration; + el::Helpers::installCustomFormatSpecifier( + el::CustomFormatSpecifier("%startTime", std::bind(getTimeSinceProgramStart))); + std::string format = "[%startTime][%level][%thread][%fbase]: %msg"; + loggerConfiguration.set(el::Level::Info, el::ConfigurationType::Format, format); + loggerConfiguration.set(el::Level::Error, el::ConfigurationType::Format, format); + loggerConfiguration.set(el::Level::Fatal, el::ConfigurationType::Format, format); + loggerConfiguration.set(el::Level::Warning, el::ConfigurationType::Format, format); + el::Helpers::setThreadName("Render"); + el::Loggers::reconfigureAllLoggers(loggerConfiguration); + el::Loggers::addFlag(el::LoggingFlag::ColoredTerminalOutput); + LOG(INFO) << "Logger is configured"; + + LOG(WARNING) << "Sizeof EventData is " << sizeof(EventData); + + ThreadGame game; + ThreadNetwork network; + ThreadRender render; + + std::thread threadGame(&ThreadGame::Execute, game); + std::thread threadNetwork(&ThreadNetwork::Execute, network); + + render.Execute(); + + threadGame.join(); + threadNetwork.join(); + return 0; }
\ No newline at end of file diff --git a/src/network/Network.cpp b/src/network/Network.cpp deleted file mode 100644 index 91cb481..0000000 --- a/src/network/Network.cpp +++ /dev/null @@ -1,220 +0,0 @@ -#include <network/Network.hpp> - -Network::Network(std::string address, unsigned short port) { - socket = new Socket(address, port); - stream = new StreamSocket(socket); -} - -Network::~Network() { - delete stream; - delete socket; -} - -std::shared_ptr<Packet> Network::ReceivePacket(ConnectionState state) { - int packetSize = stream->ReadVarInt(); - auto packetData = stream->ReadByteArray(packetSize); - StreamBuffer streamBuffer(packetData.data(), packetData.size()); - int packetId = streamBuffer.ReadVarInt(); - auto packet = ReceivePacketByPacketId(packetId, state, streamBuffer); - return packet; -} - -void Network::SendPacket(Packet &packet) { - StreamCounter packetSize; - packetSize.WriteVarInt(packet.GetPacketId()); - packet.ToStream(&packetSize); - stream->WriteVarInt(packetSize.GetCountedSize()); - stream->WriteVarInt(packet.GetPacketId()); - packet.ToStream(stream); -} - -std::shared_ptr<Packet> Network::ReceivePacketByPacketId(int packetId, ConnectionState state, StreamInput &stream) { - std::shared_ptr<Packet> packet(nullptr); - switch (state) { - case Handshaking: - switch (packetId) { - case PacketNameHandshakingCB::Handshake: - packet = std::make_shared<PacketHandshake>(); - break; - } - case Login: - switch (packetId) { - case PacketNameLoginCB::LoginSuccess: - packet = std::make_shared<PacketLoginSuccess>(); - break; - } - break; - case Play: - packet = ParsePacketPlay((PacketNamePlayCB) packetId); - break; - case Status: - break; - } - if (packet.get() != nullptr) - packet->FromStream(&stream); - return packet; -} - -std::shared_ptr<Packet> Network::ParsePacketPlay(PacketNamePlayCB id) { - switch (id) { - 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: - return std::make_shared<PacketDisconnectPlay>(); - case EntityStatus: - break; - case Explosion: - break; - case UnloadChunk: - break; - case ChangeGameState: - break; - case KeepAliveCB: - return std::make_shared<PacketKeepAliveCB>(); - case ChunkData: - return std::make_shared<PacketChunkData>(); - case Effect: - break; - case Particle: - break; - case JoinGame: - return std::make_shared<PacketJoinGame>(); - 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: - return std::make_shared<PacketPlayerPositionAndLookCB>(); - case UseBed: - break; - case DestroyEntities: - break; - case RemoveEntityEffect: - break; - case ResourcePackSend: - break; - case Respawn: - break; - case EntityHeadLook: - 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: - return std::make_shared<PacketUpdateHealth>(); - case ScoreboardObjective: - break; - case SetPassengers: - break; - case Teams: - break; - case UpdateScore: - break; - case SpawnPosition: - return std::make_shared<PacketSpawnPosition>(); - case TimeUpdate: - break; - case Title: - break; - case SoundEffect: - break; - case PlayerListHeaderAndFooter: - break; - case CollectItem: - break; - case EntityTeleport: - break; - case EntityProperties: - break; - case EntityEffect: - break; - case UnlockRecipes: - break; - case SelectAdvancementTab: - break; - case Advancements: - break; - } - return nullptr; -} diff --git a/src/network/NetworkClient.cpp b/src/network/NetworkClient.cpp deleted file mode 100644 index 73880cf..0000000 --- a/src/network/NetworkClient.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include <network/NetworkClient.hpp> - -NetworkClient::NetworkClient(std::string address, unsigned short port, std::string username, bool &quit) - : network(address, port), isRunning(quit) { - state = Handshaking; - - PacketHandshake handshake; - handshake.protocolVersion = 335; - handshake.serverAddress = "127.0.0.1"; - handshake.serverPort = 25565; - handshake.nextState = 2; - network.SendPacket(handshake); - state = Login; - - PacketLoginStart loginStart; - loginStart.Username = "HelloOne"; - network.SendPacket(loginStart); - - auto response = std::static_pointer_cast<PacketLoginSuccess>(network.ReceivePacket(Login)); - if (response->Username != username) { - throw std::logic_error("Received username is not sended username"); - } - - state = Play; - - isActive = true; - std::thread thread(&NetworkClient::NetworkLoop, this); - std::swap(networkThread, thread); -} - -NetworkClient::~NetworkClient() { - isActive = false; - networkThread.join(); -} - -std::shared_ptr<Packet> NetworkClient::ReceivePacket() { - if (toReceive.empty()) - return std::shared_ptr<Packet>(nullptr); - toReceiveMutex.lock(); - auto ret = toReceive.front(); - toReceive.pop(); - toReceiveMutex.unlock(); - return ret; -} - -void NetworkClient::SendPacket(std::shared_ptr<Packet> packet) { - toSendMutex.lock(); - toSend.push(packet); - toSendMutex.unlock(); -} - -void NetworkClient::NetworkLoop() { - auto timeOfLastKeepAlivePacket = std::chrono::steady_clock::now(); - el::Helpers::setThreadName("Network"); - LOG(INFO) << "Network thread is started"; - try { - while (isActive) { - toSendMutex.lock(); - while (!toSend.empty()) { - if (toSend.front()!=nullptr) - network.SendPacket(*toSend.front()); - toSend.pop(); - } - toSendMutex.unlock(); - auto packet = network.ReceivePacket(state); - if (packet.get() != nullptr) { - if (packet->GetPacketId() != PacketNamePlayCB::KeepAliveCB) { - toReceiveMutex.lock(); - toReceive.push(packet); - toReceiveMutex.unlock(); - } else { - timeOfLastKeepAlivePacket = std::chrono::steady_clock::now(); - auto packetKeepAlive = std::static_pointer_cast<PacketKeepAliveCB>(packet); - auto packetKeepAliveSB = std::make_shared<PacketKeepAliveSB>(packetKeepAlive->KeepAliveId); - network.SendPacket(*packetKeepAliveSB); - } - } - using namespace std::chrono_literals; - if (std::chrono::steady_clock::now() - timeOfLastKeepAlivePacket > 20s) { - auto disconnectPacket = std::make_shared<PacketDisconnectPlay>(); - disconnectPacket->Reason = "Timeout"; - toReceiveMutex.lock(); - toReceive.push(disconnectPacket); - toReceiveMutex.unlock(); - break; - } - } - } catch (std::exception &e) { - LOG(ERROR) << "Exception catched in NetworkLoop: " << e.what(); - isRunning = false; - } - LOG(INFO) << "Network thread is stopped"; -} diff --git a/src/network/Socket.cpp b/src/network/Socket.cpp deleted file mode 100644 index f4e6787..0000000 --- a/src/network/Socket.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include <network/Socket.hpp> - -Socket::Socket(std::string address, unsigned short port) { - sf::Socket::Status connectionStatus = socket.connect(sf::IpAddress(address), port); - if (connectionStatus == sf::Socket::Status::Error) - throw std::runtime_error("Can't connect to remote server"); - else if (connectionStatus != sf::Socket::Status::Done) - throw std::runtime_error("Connection failed with unknown reason"); -} - -Socket::~Socket() { - socket.disconnect(); -} - -void Socket::Read(unsigned char *buffPtr, size_t buffLen) { - size_t received = 0; - socket.receive(buffPtr, buffLen, received); - size_t totalReceived = received; - while (totalReceived < buffLen) { - if (socket.receive(buffPtr + totalReceived, buffLen - totalReceived, received) != sf::Socket::Done) - throw std::runtime_error("Raw socket data receiving is failed"); - totalReceived += received; - } -} - -void Socket::Write(unsigned char *buffPtr, size_t buffLen) { - if (socket.send(buffPtr, buffLen) != sf::Socket::Done) - throw std::runtime_error("Raw socket data sending is failed"); -} diff --git a/src/network/Stream.cpp b/src/network/Stream.cpp deleted file mode 100644 index 447b13f..0000000 --- a/src/network/Stream.cpp +++ /dev/null @@ -1,349 +0,0 @@ -#include <network/Stream.hpp> - -const int MAX_VARINT_LENGTH = 5; - -bool StreamInput::ReadBool() { - unsigned char value; - ReadData(&value, 1); - return value != 0; -} - -signed char StreamInput::ReadByte() { - signed char value; - ReadData((unsigned char *) &value, 1); - endswap(value); - return value; -} - -unsigned char StreamInput::ReadUByte() { - unsigned char value; - ReadData(&value, 1); - endswap(value); - return value; -} - -short StreamInput::ReadShort() { - unsigned short value; - ReadData((unsigned char *) &value, 2); - endswap(value); - return value; -} - -unsigned short StreamInput::ReadUShort() { - unsigned char buff[2]; - ReadData(buff, 2); - unsigned short val = *(reinterpret_cast<unsigned short *>(buff)); - endswap(val); - return val; -} - -int StreamInput::ReadInt() { - int value; - ReadData((unsigned char *) &value, 4); - endswap(value); - return value; -} - -long long StreamInput::ReadLong() { - long long value; - ReadData((unsigned char *) &value, 8); - endswap(value); - return value; -} - -float StreamInput::ReadFloat() { - float value; - ReadData((unsigned char *) &value, 4); - endswap(value); - return value; -} - -double StreamInput::ReadDouble() { - double value; - ReadData((unsigned char *) &value, 8); - endswap(value); - return value; -} - -std::string StreamInput::ReadString() { - int strLength = ReadVarInt(); - unsigned char *buff = new unsigned char[strLength + 1]; - ReadData(buff, strLength); - buff[strLength] = 0; - std::string str((char *) buff); - delete buff; - return str; -} - -std::string StreamInput::ReadChat() { - std::string str, jsonStr = ReadString(); - nlohmann::json json; - try { - json = nlohmann::json::parse(jsonStr); - } catch (std::exception &e) { - LOG(WARNING) << "Chat json parsing failed: " << e.what(); - LOG(WARNING) << "Corrupted json: " << jsonStr; - return ""; - } - if (json.find("translate") != json.end()) - if (json["translate"].get<std::string>() == "multiplayer.disconnect.kicked") - return "kicked by operator"; - for (auto &it:json["extra"]) { - str += it["text"].get<std::string>(); - } - return str; -} - -int StreamInput::ReadVarInt() { - unsigned char data[MAX_VARINT_LENGTH] = {0}; - size_t dataLen = 0; - do { - ReadData(&data[dataLen], 1); - } while ((data[dataLen++] & 0x80) != 0); - - int readed = 0; - int result = 0; - char read; - do { - read = data[readed]; - int value = (read & 0b01111111); - result |= (value << (7 * readed)); - readed++; - } while ((read & 0b10000000) != 0); - - return result; -} - -long long StreamInput::ReadVarLong() { - return 0; -} - -std::vector<unsigned char> StreamInput::ReadEntityMetadata() { - return std::vector<unsigned char>(); -} - -std::vector<unsigned char> StreamInput::ReadSlot() { - return std::vector<unsigned char>(); -} - -std::vector<unsigned char> StreamInput::ReadNbtTag() { - return std::vector<unsigned char>(); -} - -Vector StreamInput::ReadPosition() { - unsigned long long t = ReadLong(); - int x = t >> 38; - int y = (t >> 26) & 0xFFF; - int z = t << 38 >> 38; - if (x >= pow(2, 25)) { - x -= pow(2, 26); - } - if (y >= pow(2, 11)) { - y -= pow(2, 12); - } - if (z >= pow(2, 25)) { - z -= pow(2, 26); - } - return Vector(x, y, z); -} - -unsigned char StreamInput::ReadAngle() { - return ReadUByte(); -} - -std::vector<unsigned char> StreamInput::ReadUuid() { - unsigned char buff[16]; - ReadData(buff, 16); - endswap(buff, 16); - return std::vector<unsigned char>(buff, buff + 16); -} - -std::vector<unsigned char> StreamInput::ReadByteArray(size_t arrLength) { - unsigned char *buffer = new unsigned char[arrLength]; - ReadData(buffer, arrLength); - std::vector<unsigned char> ret(buffer, buffer + arrLength); - delete buffer; - return ret; - -} - -void StreamOutput::WriteBool(bool value) { - unsigned char val = value ? 1 : 0; - endswap(val); - WriteData(&val, 1); -} - -void StreamOutput::WriteByte(signed char value) { - endswap(value); - WriteData((unsigned char *) &value, 1); -} - -void StreamOutput::WriteUByte(unsigned char value) { - endswap(value); - WriteData(&value, 1); -} - -void StreamOutput::WriteShort(short value) { - endswap(value); - WriteData((unsigned char *) &value, 2); -} - -void StreamOutput::WriteUShort(unsigned short value) { - endswap(value); - WriteData((unsigned char *) &value, 2); -} - -void StreamOutput::WriteInt(int value) { - endswap(value); - WriteData((unsigned char *) &value, 4); -} - -void StreamOutput::WriteLong(long long value) { - endswap(value); - WriteData((unsigned char *) &value, 8); -} - -void StreamOutput::WriteFloat(float value) { - endswap(value); - WriteData((unsigned char *) &value, 4); -} - -void StreamOutput::WriteDouble(double value) { - endswap(value); - WriteData((unsigned char *) &value, 8); -} - -void StreamOutput::WriteString(std::string value) { - WriteVarInt(value.size()); - WriteData((unsigned char *) value.data(), value.size()); -} - -void StreamOutput::WriteChat(std::string value) { - WriteString(value); -} - -void StreamOutput::WriteVarInt(int value) { - unsigned char buff[5]; - size_t len = 0; - do { - unsigned char temp = (unsigned char) (value & 0b01111111); - value >>= 7; - if (value != 0) { - temp |= 0b10000000; - } - buff[len] = temp; - len++; - } while (value != 0); - WriteData(buff, len); -} - -void StreamOutput::WriteVarLong(long long value) { - unsigned char buff[10]; - size_t len = 0; - do { - unsigned char temp = (unsigned char) (value & 0b01111111); - value >>= 7; - if (value != 0) { - temp |= 0b10000000; - } - buff[len] = temp; - len++; - } while (value != 0); - WriteData(buff, len); -} - -void StreamOutput::WriteEntityMetadata(std::vector<unsigned char> value) { - LOG(FATAL) << "Used unimplemented WriteEntityMetadata: " << value.size(); -} - -void StreamOutput::WriteSlot(std::vector<unsigned char> value) { - LOG(FATAL) << "Used unimplemented WriteSlot " << value.size(); -} - -void StreamOutput::WriteNbtTag(std::vector<unsigned char> value) { - LOG(FATAL) << "Used unimplemented WriteNbtTag " << value.size(); -} - -void StreamOutput::WritePosition(Vector value) { - LOG(FATAL) << "Used unimplemented Position: " << value.GetX() << ", " << value.GetY() << " " << value.GetZ(); -} - -void StreamOutput::WriteAngle(unsigned char value) { - WriteUByte(value); -} - -void StreamOutput::WriteUuid(std::vector<unsigned char> value) { - WriteByteArray(value); -} - -void StreamOutput::WriteByteArray(std::vector<unsigned char> value) { - WriteData(value.data(), value.size()); -} - -void StreamBuffer::ReadData(unsigned char *buffPtr, size_t buffLen) { - size_t bufferLengthLeft = buffer + bufferLength - bufferPtr; - if (bufferLengthLeft < buffLen) - throw std::runtime_error("Required data is more, than in buffer available"); - std::memcpy(buffPtr, bufferPtr, buffLen); - bufferPtr += buffLen; -} - -void StreamBuffer::WriteData(unsigned char *buffPtr, size_t buffLen) { - size_t bufferLengthLeft = buffer + bufferLength - bufferPtr; - if (bufferLengthLeft < buffLen) - throw std::runtime_error("Required data is more, than in buffer available"); - std::memcpy(bufferPtr, buffPtr, buffLen); - bufferPtr += buffLen; -} - -StreamBuffer::StreamBuffer(unsigned char *data, size_t dataLen) { - buffer = new unsigned char[dataLen]; - bufferPtr = buffer; - bufferLength = dataLen; - std::memcpy(buffer, data, dataLen); -} - -StreamBuffer::StreamBuffer(size_t bufferLen) { - buffer = new unsigned char[bufferLen]; - bufferPtr = buffer; - bufferLength = bufferLen; - for (unsigned char *p = buffer; p != buffer + bufferLength; ++p) - *p = 0; -} - -StreamBuffer::~StreamBuffer() { - delete buffer; -} - -std::vector<unsigned char> StreamBuffer::GetBuffer() { - return std::vector<unsigned char>(buffer, buffer + bufferLength); -} - -void StreamCounter::WriteData(unsigned char *buffPtr, size_t buffLen) { - buffPtr++; - size += buffLen; -} - -StreamCounter::StreamCounter(size_t initialSize) : size(initialSize) { - -} - -StreamCounter::~StreamCounter() { - -} - -size_t StreamCounter::GetCountedSize() { - return size; -} - -void StreamSocket::ReadData(unsigned char *buffPtr, size_t buffLen) { - socket->Read(buffPtr, buffLen); -} - -void StreamSocket::WriteData(unsigned char *buffPtr, size_t buffLen) { - socket->Write(buffPtr, buffLen); -} - -StreamSocket::StreamSocket(Socket *socketPtr) : socket(socketPtr) { - -}
\ No newline at end of file diff --git a/src/world/Block.cpp b/src/world/Block.cpp deleted file mode 100644 index 74ac406..0000000 --- a/src/world/Block.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include <world/Block.hpp> - -Block::~Block() {} - -Block::Block(unsigned short id, unsigned char state) : id(id), state(state) {} - -Block::Block() : id(0), state(0) {} - -bool operator<(const Block &lhs, const Block &rhs) { - if (lhs.id < rhs.id) - return true; - if (lhs.id == rhs.id) { - if (lhs.state != rhs.state) - return lhs.state < rhs.state; - } - return false; -} diff --git a/src/world/Collision.cpp b/src/world/Collision.cpp deleted file mode 100644 index 8fc562b..0000000 --- a/src/world/Collision.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include <world/Collision.hpp> - -bool TestCollision(AABB first, AABB second) { - double firstXl = first.x; - double firstXr = first.x + first.w; - - double firstYl = first.y; - double firstYr = first.y + first.h; - - double firstZl = first.z; - double firstZr = first.z + first.l; - - - double secondXl = second.x; - double secondXr = second.x + second.w; - - double secondYl = second.y; - double secondYr = second.y + second.h; - - double secondZl = second.z; - double secondZr = second.z + second.l; - - bool collidesOnX = firstXr >= secondXl && firstXl <= secondXr; - bool collidesOnY = firstYr >= secondYl && firstYl <= secondYr; - bool collidesOnZ = firstZr >= secondZl && firstZl <= secondZr; - - return collidesOnX && collidesOnY && collidesOnZ; -} diff --git a/src/world/GameState.cpp b/src/world/GameState.cpp deleted file mode 100644 index 79e2f1b..0000000 --- a/src/world/GameState.cpp +++ /dev/null @@ -1,383 +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<PacketPlayerPositionAndLookSB>(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<PacketPlayerPosition>(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<PacketDisconnectPlay>(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<PacketChunkData>(ptr); - world.ParseChunkData(packet); - break; - } - case Effect: - break; - case Particle: - break; - case JoinGame: { - auto packet = std::static_pointer_cast<PacketJoinGame>(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<PacketPlayerPositionAndLookCB>(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<PacketTeleportConfirm>(packet->TeleportId); - auto packetPerformRespawn = std::make_shared<PacketClientStatus>(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<PacketUpdateHealth>(ptr); - g_PlayerHealth = packet->Health; - if (g_PlayerHealth <= 0) { - LOG(INFO) << "Player is dead. Respawning..."; - auto packetPerformRespawn = std::make_shared<PacketClientStatus>(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<PacketSpawnPosition>(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; -} - -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<PacketPlayerLook>(g_PlayerYaw, g_PlayerPitch, g_OnGround); - nc->SendPacket(updatePacket); -} - -glm::mat4 GameState::GetViewMatrix() { - auto pos = this->Position(); - pos.y+=1.62; - return glm::lookAt(pos, pos + 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, g_PlayerY, g_PlayerZ); -} - -void GameState::SetPosition(glm::vec3 Position) { - g_PlayerX = Position.x; - g_PlayerY = Position.y; - g_PlayerZ = Position.z; -} diff --git a/src/world/Section.cpp b/src/world/Section.cpp deleted file mode 100644 index d97d163..0000000 --- a/src/world/Section.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include <world/Section.hpp> - - -Section::Section(Vector position, byte *dataBlocks, size_t dataBlocksLength, byte *dataLight, byte *dataSky, - byte bitsPerBlock, - std::vector<unsigned short> palette) { - worldPosition = position; - - m_dataBlocksLen = dataBlocksLength; - m_dataBlocks = new byte[m_dataBlocksLen]; - std::copy(dataBlocks, dataBlocks + m_dataBlocksLen, m_dataBlocks); - - m_dataLight = new byte[2048]; - std::copy(dataLight, dataLight + 2048, m_dataLight); - - if (dataSky) { - m_dataSkyLight = new byte[2048]; - std::copy(dataSky, dataSky + 2048, m_dataSkyLight); - } - - m_palette = palette; - m_bitsPerBlock = bitsPerBlock; -} - -Section::~Section() { - delete[] m_dataBlocks; - m_dataBlocksLen = 0; - m_dataBlocks = nullptr; - delete[] m_dataLight; - m_dataLight = nullptr; - delete[] m_dataSkyLight; - m_dataSkyLight = nullptr; -} - -Block &Section::GetBlock(Vector pos) { - return m_blocks[pos.GetY() * 256 + pos.GetZ() * 16 + pos.GetX()]; -} - -void Section::Parse() { - if (m_dataBlocks == nullptr) - return; - - long long *longArray = reinterpret_cast<long long *>(m_dataBlocks); - for (size_t i = 0; i < m_dataBlocksLen / 8; i++) - endswap(&longArray[i]); - std::vector<unsigned short> blocks; - blocks.reserve(4096); - int bitPos = 0; - unsigned short t = 0; - for (size_t i = 0; i < m_dataBlocksLen; i++) { - for (int j = 0; j < 8; j++) { - t |= (m_dataBlocks[i] & 0x01) ? 0x80 : 0x00; - t >>= 1; - m_dataBlocks[i] >>= 1; - bitPos++; - if (bitPos >= m_bitsPerBlock) { - bitPos = 0; - t >>= m_bitsPerBlock - 1; - blocks.push_back(t); - t = 0; - } - } - } - - std::vector<byte> light; - light.reserve(4096); - for (int i = 0; i < 2048; i++) { - byte t = m_dataLight[i]; - byte first = t & 0b11110000; - byte second = t >> 4; - light.push_back(first); - light.push_back(second); - } - for (int i = 0; i < 4096; i++) { - unsigned short blockId = m_palette.size() > 0 ? m_palette[blocks[i]] : blocks[i]; - Block block(blockId >> 4, blockId & 0xF); - m_blocks.push_back(block); - } - if ((light.size() + blocks.size()) / 2 != 4096) { - throw 118; - } - delete[] m_dataBlocks; - m_dataBlocksLen = 0; - m_dataBlocks = nullptr; - delete[] m_dataLight; - m_dataLight = nullptr; - delete[] m_dataSkyLight; - m_dataSkyLight = nullptr; - - parseWaiter.notify_all(); -} - -Section &Section::operator=(Section other) { - std::swap(*this, other); - return *this; -} - -void swap(Section &a, Section &b) { - using std::swap; - swap(a.m_dataBlocksLen, b.m_dataBlocksLen); - swap(a.m_dataBlocks, b.m_dataBlocks); - swap(a.m_dataLight, b.m_dataLight); - swap(a.m_dataSkyLight, b.m_dataSkyLight); - swap(a.m_blocks, b.m_blocks); - swap(a.m_palette, b.m_palette); - swap(a.m_bitsPerBlock, b.m_bitsPerBlock); -} - -Section::Section(const Section &other) { - worldPosition = other.worldPosition; - m_dataBlocksLen = other.m_dataBlocksLen; - if (other.m_blocks.empty()) { - m_dataBlocks = new byte[m_dataBlocksLen]; - std::copy(other.m_dataBlocks, other.m_dataBlocks + m_dataBlocksLen, m_dataBlocks); - - m_dataLight = new byte[2048]; - std::copy(other.m_dataLight, other.m_dataLight + 2048, m_dataLight); - - if (other.m_dataSkyLight) { - m_dataSkyLight = new byte[2048]; - std::copy(other.m_dataSkyLight, other.m_dataSkyLight + 2048, m_dataSkyLight); - } - } else { - std::copy(other.m_blocks.begin(), other.m_blocks.end(), std::back_inserter(m_blocks)); - } - - m_palette = other.m_palette; - m_bitsPerBlock = other.m_bitsPerBlock; -} - -Vector Section::GetPosition() { - return worldPosition; -} diff --git a/src/world/World.cpp b/src/world/World.cpp deleted file mode 100644 index c83bdce..0000000 --- a/src/world/World.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include <world/World.hpp> - -void World::ParseChunkData(std::shared_ptr<PacketChunkData> packet) { - StreamBuffer chunkData(packet->Data.data(), packet->Data.size()); - std::bitset<16> bitmask(packet->PrimaryBitMask); - for (int i = 0; i < 16; i++) { - if (bitmask[i]) { - Vector chunkPosition = Vector(packet->ChunkX, i, packet->ChunkZ); - Section section = ParseSection(&chunkData, chunkPosition); - section.Parse(); - sectionMutexes[chunkPosition].lock(); - auto it = sections.find(chunkPosition); - if (it == sections.end()) { - sections.insert(std::make_pair(chunkPosition, section)); - } else { - using std::swap; - swap(it->second, section); - } - sectionMutexes[chunkPosition].unlock(); - } - } -} - -Section World::ParseSection(StreamInput *data, Vector position) { - unsigned char bitsPerBlock = data->ReadUByte(); - int paletteLength = data->ReadVarInt(); - std::vector<unsigned short> palette; - for (int i = 0; i < paletteLength; i++) { - palette.push_back(data->ReadVarInt()); - } - int dataArrayLength = data->ReadVarInt(); - auto dataArray = data->ReadByteArray(dataArrayLength * 8); - auto blockLight = data->ReadByteArray(4096 / 2); - std::vector<unsigned char> skyLight; - if (dimension == 0) - skyLight = data->ReadByteArray(4096 / 2); - return Section(position, dataArray.data(), dataArray.size(), blockLight.data(), - (skyLight.size() > 0 ? skyLight.data() : nullptr), bitsPerBlock, palette); -} - -World::~World() { -} - -World::World() { - -} - -bool World::isPlayerCollides(double X, double Y, double Z) { - Vector PlayerChunk(floor(X / 16.0), floor(Y / 16.0), floor(Z / 16.0)); - std::vector<Vector> closestSectionsCoordinates = { - Vector(PlayerChunk.GetX(), PlayerChunk.GetY(), PlayerChunk.GetZ()), - Vector(PlayerChunk.GetX() + 1, PlayerChunk.GetY(), PlayerChunk.GetZ()), - Vector(PlayerChunk.GetX() - 1, PlayerChunk.GetY(), PlayerChunk.GetZ()), - Vector(PlayerChunk.GetX(), PlayerChunk.GetY() + 1, PlayerChunk.GetZ()), - Vector(PlayerChunk.GetX(), PlayerChunk.GetY() - 1, PlayerChunk.GetZ()), - Vector(PlayerChunk.GetX(), PlayerChunk.GetY(), PlayerChunk.GetZ() + 1), - Vector(PlayerChunk.GetX(), PlayerChunk.GetY(), PlayerChunk.GetZ() - 1), - }; - std::vector<std::map<Vector, Section>::iterator> closestSections; - for (auto &coord:closestSectionsCoordinates) { - auto it = sections.find(coord); - if (it != sections.end()) - closestSections.push_back(it); - } - if (closestSections.empty()) - return false; - - for (auto &it:closestSections) { - - const double PlayerWidth = 0.6; - const double PlayerHeight = 1.82; - const double PlayerLength = 0.6; - - AABB playerColl; - playerColl.x = X - PlayerWidth / 2.0; - playerColl.w = PlayerWidth; - playerColl.y = Y; - playerColl.h = PlayerHeight; - playerColl.z = Z - PlayerLength / 2.0; - playerColl.l = PlayerLength; - - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - Block block = it->second.GetBlock(Vector(x, y, z)); - if (block.id == 0 || block.id == 31) - continue; - AABB blockColl{(x + it->first.GetX() * 16.0), - (y + it->first.GetY() * 16.0), - (z + it->first.GetZ() * 16.0), 1, 1, 1}; - if (TestCollision(playerColl, blockColl)) - return true; - } - } - } - } - return false; -} - -Block &World::GetBlock(Vector pos) { - Vector sectionPos (floor(pos.GetX() / 16.0f),floor(pos.GetY() / 16.0f),floor(pos.GetZ()/16.0f)); - Vector inSectionPos = pos - (sectionPos * 16); - if (sections.find(sectionPos)==sections.end()){ - static Block block(0,0); - return block; - } - sectionMutexes[sectionPos].lock(); - Block& block = sections.find(sectionPos)->second.GetBlock(inSectionPos); - sectionMutexes[sectionPos].unlock(); - return block; -} - -std::vector<Vector> World::GetSectionsList() { - std::vector<Vector> sectionsList; - for (auto& it:sections) { - sectionsList.push_back(it.first); - } - return sectionsList; -} - -Section &World::GetSection(Vector sectionPos) { - sectionMutexes[sectionPos].lock(); - sectionMutexes[sectionPos].unlock(); - return sections.find(sectionPos)->second; -} - -glm::vec3 World::Raycast(glm::vec3 position, glm::vec3 direction, float maxLength, float minPrecision) { - return glm::vec3(position * direction / maxLength * minPrecision); -} |