From cea3a0ca2814e75ca19575a71c5be4be1c13a90f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9?= Date: Sun, 9 Feb 2025 23:52:04 +0600 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BF=D0=B0=D0=BA=D0=B5=D1=82=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 4 +- Src/Client/Abstract.cpp | 17 +- Src/Client/Abstract.hpp | 112 ++++----- Src/Client/ServerSession.cpp | 275 +++++++++++++++++++++- Src/Client/ServerSession.hpp | 51 +++- Src/Client/Vulkan/Vulkan.cpp | 265 ++++++++++++++++----- Src/Client/Vulkan/Vulkan.hpp | 56 ++--- Src/Client/Vulkan/VulkanRenderSession.cpp | 63 +++++ Src/Client/Vulkan/VulkanRenderSession.hpp | 43 ++++ Src/Common/Abstract.hpp | 24 +- Src/Common/Async.hpp | 4 +- Src/Common/Lockable.hpp | 2 + Src/Common/Net.cpp | 20 +- Src/Common/Net.hpp | 29 ++- Src/Common/Packets.hpp | 19 +- Src/Server/Abstract.hpp | 14 -- Src/Server/GameServer.cpp | 13 +- Src/Server/GameServer.hpp | 3 +- Src/Server/RemoteClient.cpp | 101 ++++++-- Src/Server/RemoteClient.hpp | 11 +- Src/assets.cpp | 2 +- Src/assets.hpp | 2 +- Src/main.cpp | 60 +++-- Work/assets/default.ttf | Bin 0 -> 111816 bytes Work/assets/default2.ttf | Bin 0 -> 71608 bytes Work/imgui.ini | 6 +- 26 files changed, 927 insertions(+), 269 deletions(-) create mode 100644 Src/Client/Vulkan/VulkanRenderSession.cpp create mode 100644 Src/Client/Vulkan/VulkanRenderSession.hpp create mode 100644 Work/assets/default.ttf create mode 100644 Work/assets/default2.ttf diff --git a/CMakeLists.txt b/CMakeLists.txt index edd7ed8..e57adae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.13) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections") -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections -rdynamic") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") # -rdynamic project (LuaVox VERSION 0.0 DESCRIPTION "LuaVox Description") add_executable(${PROJECT_NAME}) @@ -65,8 +65,8 @@ add_custom_command(OUTPUT assets.o resources.cpp INPUT ${ASSETS} COMMAND cd "${CMAKE_CURRENT_SOURCE_DIR}/Work/assets" && ld -r -b binary -o '${CMAKE_CURRENT_BINARY_DIR}/assets.o' ${ASSETS} COMMAND objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents ${CMAKE_CURRENT_BINARY_DIR}/assets.o ${CMAKE_CURRENT_BINARY_DIR}/assets.o) -add_library(assets STATIC resources.cpp assets.o) SET_SOURCE_FILES_PROPERTIES(assets.o PROPERTIES EXTERNAL_OBJECT true GENERATED true) +add_library(assets STATIC resources.cpp assets.o) SET_TARGET_PROPERTIES(assets PROPERTIES LINKER_LANGUAGE C) target_link_libraries(${PROJECT_NAME} PUBLIC assets uring) diff --git a/Src/Client/Abstract.cpp b/Src/Client/Abstract.cpp index 14284f2..1c9c49b 100644 --- a/Src/Client/Abstract.cpp +++ b/Src/Client/Abstract.cpp @@ -1,25 +1,10 @@ #include "Abstract.hpp" +#include "Common/Abstract.hpp" namespace LV::Client { - void IRenderSession::onChunksChange(WorldId_t worldId, const std::vector &changeOrAddList, const std::vector &remove) {} - void IRenderSession::attachCameraToEntity(EntityId_t id) {} - void IRenderSession::onWorldAdd(WorldId_t id) {} - void IRenderSession::onWorldRemove(WorldId_t id) {} - void IRenderSession::onWorldChange(WorldId_t id) {} - void IRenderSession::onEntitysAdd(const std::vector &list) {} - void IRenderSession::onEntitysRemove(const std::vector &list) {} - void IRenderSession::onEntitysPosQuatChanges(const std::vector &list) {} - void IRenderSession::onEntitysStateChanges(const std::vector &list) {} - TextureId_t IRenderSession::allocateTexture() { return 0; } - void IRenderSession::freeTexture(TextureId_t id) {} - void IRenderSession::setTexture(TextureId_t id, TextureInfo info) {} - ModelId_t IRenderSession::allocateModel() { return 0; } - void IRenderSession::freeModel(ModelId_t id) {} - void IRenderSession::setModel(ModelId_t id, ModelInfo info) {} IRenderSession::~IRenderSession() = default; - IServerSession::~IServerSession() = default; void ISurfaceEventListener::onResize(uint32_t width, uint32_t height) {} diff --git a/Src/Client/Abstract.hpp b/Src/Client/Abstract.hpp index 21d574e..644e71c 100644 --- a/Src/Client/Abstract.hpp +++ b/Src/Client/Abstract.hpp @@ -9,17 +9,13 @@ namespace LV::Client { -using VoxelId_t = uint16_t; - struct VoxelCube { + DefVoxelId_c VoxelId; Pos::Local256 Left, Right; - VoxelId_t Material; }; -using NodeId_t = uint16_t; - struct Node { - NodeId_t NodeId; + DefNodeId_c NodeId; uint8_t Rotate : 6; }; @@ -34,15 +30,11 @@ struct Chunk { LightPrism Lights[16][16]; }; -using WorldId_t = uint8_t; -using PortalId_t = uint16_t; -using EntityId_t = uint16_t; - class Entity { public: // PosQuat - WorldId_t WorldId; - PortalId_t LastUsedPortal; + DefWorldId_c WorldId; + DefPortalId_c LastUsedPortal; Pos::Object Pos; glm::quat Quat; static constexpr uint16_t HP_BS = 4096, HP_BS_Bit = 12; @@ -54,51 +46,24 @@ public: // states }; -using TextureId_t = uint16_t; - -struct TextureInfo { - -}; - -using ModelId_t = uint16_t; - -struct ModelInfo { - -}; - /* Интерфейс рендера текущего подключения к серверу */ class IRenderSession { public: + virtual void onDefTexture(TextureId_c id, std::vector &&info) = 0; + virtual void onDefTextureLost(const std::vector &&lost) = 0; + virtual void onDefModel(ModelId_c id, std::vector &&info) = 0; + virtual void onDefModelLost(const std::vector &&lost) = 0; + + virtual void onDefWorldUpdates(const std::vector &updates) = 0; + virtual void onDefVoxelUpdates(const std::vector &updates) = 0; + virtual void onDefNodeUpdates(const std::vector &updates) = 0; + virtual void onDefPortalUpdates(const std::vector &updates) = 0; + virtual void onDefEntityUpdates(const std::vector &updates) = 0; + // Сообщаем об изменившихся чанках - virtual void onChunksChange(WorldId_t worldId, const std::vector &changeOrAddList, const std::vector &remove); - // Подключаем камеру к сущности - virtual void attachCameraToEntity(EntityId_t id); - - // - - // Мир уже есть в глобальном списке - virtual void onWorldAdd(WorldId_t id); - // Мира уже нет в списке - virtual void onWorldRemove(WorldId_t id); - // Изменение состояния мира - virtual void onWorldChange(WorldId_t id); - - // Сущности уже есть в глобальном списке - virtual void onEntitysAdd(const std::vector &list); - // - virtual void onEntitysRemove(const std::vector &list); - // - virtual void onEntitysPosQuatChanges(const std::vector &list); - // - virtual void onEntitysStateChanges(const std::vector &list); - - virtual TextureId_t allocateTexture(); - virtual void freeTexture(TextureId_t id); - virtual void setTexture(TextureId_t id, TextureInfo info); - - virtual ModelId_t allocateModel(); - virtual void freeModel(ModelId_t id); - virtual void setModel(ModelId_t id, ModelInfo info); + virtual void onChunksChange(WorldId_c worldId, const std::vector &changeOrAddList, const std::vector &remove) = 0; + // Установить позицию для камеры + virtual void setCameraPos(WorldId_c worldId, Pos::Object pos, glm::quat quat) = 0; virtual ~IRenderSession(); }; @@ -110,13 +75,25 @@ struct Region { struct World { - std::vector Entitys; + std::vector Entitys; std::unordered_map Regions; }; -class ChunksIterator { -public: +struct DefWorldInfo { + +}; + +struct DefPortalInfo { + +}; + +struct DefEntityInfo { + +}; + +struct WorldInfo { + }; struct VoxelInfo { @@ -127,13 +104,28 @@ struct NodeInfo { }; +struct PortalInfo { + +}; + +struct EntityInfo { + +}; + /* Интерфейс обработчика сессии с сервером */ class IServerSession { public: - std::unordered_map Entitys; - std::unordered_map Worlds; - std::unordered_map VoxelRegistry; - std::unordered_map NodeRegistry; + struct { + std::unordered_map DefWorlds; + std::unordered_map DefVoxels; + std::unordered_map DefNodes; + std::unordered_map DefPortals; + std::unordered_map DefEntityes; + + std::unordered_map Worlds; + std::unordered_map Portals; + std::unordered_map Entityes; + } Registry; virtual ~IServerSession(); }; diff --git a/Src/Client/ServerSession.cpp b/Src/Client/ServerSession.cpp index 44783f2..8e98ea9 100644 --- a/Src/Client/ServerSession.cpp +++ b/Src/Client/ServerSession.cpp @@ -1,17 +1,24 @@ #include "ServerSession.hpp" +#include "Client/Abstract.hpp" #include "Common/Net.hpp" #include #include #include #include #include +#include +#include +#include namespace LV::Client { using namespace TOS; -ServerSession::~ServerSession() = default; +ServerSession::~ServerSession() { + WorkDeadline.cancel(); + UseLock.wait_no_use(); +} coro<> ServerSession::asyncAuthorizeWithServer(tcp::socket &socket, const std::string username, const std::string token, int a_ar_r, std::function onProgress) { assert(a_ar_r >= 0 && a_ar_r <= 2); @@ -109,4 +116,270 @@ coro> ServerSession::asyncInitGameProtocol(asi co_return std::make_unique(ioc, std::move(socket)); } +void ServerSession::shutdown(EnumDisconnect type) { + IsGoingShutdown = true; + Net::Packet packet; + packet << (uint8_t) ToServer::L1::System + << (uint8_t) ToServer::L2System::Disconnect + << (uint8_t) type; + + Socket->pushPacket(std::move(packet)); + + std::string reason; + if(type == EnumDisconnect::ByInterface) + reason = "по запросу интерфейса"; + else if(type == EnumDisconnect::CriticalError) + reason = "на сервере произошла критическая ошибка"; + else if(type == EnumDisconnect::ProtocolError) + reason = "ошибка протокола (клиент)"; + + LOG.info() << "Отключение от сервера: " << reason; +} + +void ServerSession::onResize(uint32_t width, uint32_t height) { + +} + +void ServerSession::onChangeFocusState(bool isFocused) { + +} + +void ServerSession::onCursorPosChange(int32_t width, int32_t height) { + +} + +void ServerSession::onCursorMove(float xMove, float yMove) { + glm::vec3 front = Camera.Quat*glm::vec3(0.0f, 0.0f, -1.0f); +} + +void ServerSession::onFrameRendering() { + +} + +void ServerSession::onFrameRenderEnd() { + +} + +void ServerSession::onCursorBtn(ISurfaceEventListener::EnumCursorBtn btn, bool state) { + +} + +void ServerSession::onKeyboardBtn(int btn, int state) { + if(btn == GLFW_KEY_TAB && !state) { + CursorMode = CursorMode == EnumCursorMoveMode::Default ? EnumCursorMoveMode::MoveAndHidden : EnumCursorMoveMode::Default; + } +} + +void ServerSession::onJoystick() { + +} + +coro<> ServerSession::run() { + auto useLock = UseLock.lock(); + + try { + while(!IsGoingShutdown && IsConnected) { + co_await readPacket(*Socket); + } + } catch(const std::exception &exc) { + if(const auto *errc = dynamic_cast(&exc); + errc && errc->code() == boost::asio::error::operation_aborted) + { + co_return; + } + + TOS::Logger("ServerSession").warn() << exc.what(); + } + + IsConnected = false; + + co_return; +} + +void ServerSession::protocolError() { + shutdown(EnumDisconnect::ProtocolError); +} + +coro<> ServerSession::readPacket(Net::AsyncSocket &sock) { + uint8_t first = co_await sock.read(); + + switch((ToClient::L1) first) { + case ToClient::L1::System: co_await rP_System(sock); co_return; + case ToClient::L1::Resource: co_await rP_Resource(sock); co_return; + case ToClient::L1::Definition: co_await rP_Definition(sock); co_return; + case ToClient::L1::Content: co_await rP_Content(sock); co_return; + default: + protocolError(); + } +} + +coro<> ServerSession::rP_System(Net::AsyncSocket &sock) { + uint8_t second = co_await sock.read(); + + switch((ToClient::L2System) second) { + case ToClient::L2System::Init: + + co_return; + case ToClient::L2System::Disconnect: + { + EnumDisconnect type = (EnumDisconnect) co_await sock.read(); + std::string reason = co_await sock.read(); + + if(type == EnumDisconnect::ByInterface) + reason = "по запросу интерфейса " + reason; + else if(type == EnumDisconnect::CriticalError) + reason = "на сервере произошла критическая ошибка " + reason; + else if(type == EnumDisconnect::ProtocolError) + reason = "ошибка протокола (сервер) " + reason; + + LOG.info() << "Отключение от сервера: " << reason; + + co_return; + } + case ToClient::L2System::LinkCameraToEntity: + + co_return; + case ToClient::L2System::UnlinkCamera: + + co_return; + default: + protocolError(); + } +} + +coro<> ServerSession::rP_Resource(Net::AsyncSocket &sock) { + uint8_t second = co_await sock.read(); + + switch((ToClient::L2Resource) second) { + case ToClient::L2Resource::Texture: + + co_return; + case ToClient::L2Resource::FreeTexture: + + co_return; + case ToClient::L2Resource::Sound: + + co_return; + case ToClient::L2Resource::FreeSound: + + co_return; + case ToClient::L2Resource::Model: + + co_return; + case ToClient::L2Resource::FreeModel: + + co_return; + case ToClient::L2Resource::InitResSend: + + co_return; + case ToClient::L2Resource::ChunkSend: + + co_return; + case ToClient::L2Resource::SendCanceled: + + co_return; + default: + protocolError(); + } +} + +coro<> ServerSession::rP_Definition(Net::AsyncSocket &sock) { + uint8_t second = co_await sock.read(); + + switch((ToClient::L2Definition) second) { + case ToClient::L2Definition::World: + + co_return; + case ToClient::L2Definition::FreeWorld: + + co_return; + case ToClient::L2Definition::Voxel: + + co_return; + case ToClient::L2Definition::FreeVoxel: + + co_return; + case ToClient::L2Definition::Node: + + co_return; + case ToClient::L2Definition::FreeNode: + + co_return; + case ToClient::L2Definition::Portal: + + co_return; + case ToClient::L2Definition::FreePortal: + + co_return; + case ToClient::L2Definition::Entity: + + co_return; + case ToClient::L2Definition::FreeEntity: + + co_return; + default: + protocolError(); + } +} + +coro<> ServerSession::rP_Content(Net::AsyncSocket &sock) { + uint8_t second = co_await sock.read(); + + switch((ToClient::L2Content) second) { + case ToClient::L2Content::World: + + co_return; + case ToClient::L2Content::RemoveWorld: + + co_return; + case ToClient::L2Content::Portal: + + co_return; + case ToClient::L2Content::RemovePortal: + + co_return; + case ToClient::L2Content::Entity: + + co_return; + case ToClient::L2Content::RemoveEntity: + + co_return; + case ToClient::L2Content::ChunkVoxels: + { + WorldId_c wcId = co_await sock.read(); + Pos::GlobalChunk::Key posKey = co_await sock.read(); + Pos::GlobalChunk pos = *(Pos::GlobalChunk*) &posKey; + + std::vector cubes(co_await sock.read()); + + for(size_t iter = 0; iter < cubes.size(); iter++) { + VoxelCube &cube = cubes[iter]; + cube.VoxelId = co_await sock.read(); + cube.Left.X = co_await sock.read(); + cube.Left.Y = co_await sock.read(); + cube.Left.Z = co_await sock.read(); + cube.Right.X = co_await sock.read(); + cube.Right.Y = co_await sock.read(); + cube.Right.Z = co_await sock.read(); + } + + LOG.info() << "Приняты воксели чанка " << int(wcId) << " / " << pos.X << ":" << pos.Y << ":" << pos.Z << " Вокселей " << cubes.size(); + + co_return; + } + + case ToClient::L2Content::ChunkNodes: + + co_return; + case ToClient::L2Content::ChunkLightPrism: + + co_return; + case ToClient::L2Content::RemoveChunk: + + co_return; + default: + protocolError(); + } +} + } \ No newline at end of file diff --git a/Src/Client/ServerSession.hpp b/Src/Client/ServerSession.hpp index 0c58b12..d2ff2cd 100644 --- a/Src/Client/ServerSession.hpp +++ b/Src/Client/ServerSession.hpp @@ -1,7 +1,10 @@ #pragma once #include "Abstract.hpp" +#include "Common/Async.hpp" +#include "Common/Lockable.hpp" #include "Common/Net.hpp" +#include "Common/Packets.hpp" #include #include @@ -9,16 +12,23 @@ namespace LV::Client { class ServerSession : public AsyncObject, public IServerSession, public ISurfaceEventListener { - std::unique_ptr _Socket; - Net::AsyncSocket &Socket; + std::unique_ptr Socket; IRenderSession *RS = nullptr; + DestroyLock UseLock; + bool IsConnected = true, IsGoingShutdown = false; + + TOS::Logger LOG = "ServerSession"; + + struct { + glm::quat Quat; + } Camera; public: // Нужен сокет, на котором только что был согласован игровой протокол (asyncInitGameProtocol) ServerSession(asio::io_context &ioc, std::unique_ptr &&socket, IRenderSession *rs = nullptr) - : AsyncObject(ioc), _Socket(std::move(socket)), Socket(*socket), RS(rs) + : AsyncObject(ioc), Socket(std::move(socket)), RS(rs) { - assert(socket.get()); + assert(Socket.get()); co_spawn(run()); } @@ -29,23 +39,38 @@ public: // Начать игровой протокол в авторизированном сокете static coro> asyncInitGameProtocol(asio::io_context &ioc, tcp::socket &&socket, std::function onProgress = nullptr); + void shutdown(EnumDisconnect type); + + bool isConnected() { + return IsConnected; + } + + void waitShutdown() { + UseLock.wait_no_use(); + } // ISurfaceEventListener - // virtual void onResize(uint32_t width, uint32_t height) override; - // virtual void onChangeFocusState(bool isFocused) override; - // virtual void onCursorPosChange(int32_t width, int32_t height) override; - // virtual void onCursorMove(float xMove, float yMove) override; - // virtual void onFrameRendering() override; - // virtual void onFrameRenderEnd() override; + virtual void onResize(uint32_t width, uint32_t height) override; + virtual void onChangeFocusState(bool isFocused) override; + virtual void onCursorPosChange(int32_t width, int32_t height) override; + virtual void onCursorMove(float xMove, float yMove) override; + virtual void onFrameRendering() override; + virtual void onFrameRenderEnd() override; - // virtual void onCursorBtn(EnumCursorBtn btn, bool state) override; - // virtual void onKeyboardBtn(int btn, int state) override; - // virtual void onJoystick() override; + virtual void onCursorBtn(EnumCursorBtn btn, bool state) override; + virtual void onKeyboardBtn(int btn, int state) override; + virtual void onJoystick() override; private: coro<> run(); + void protocolError(); + coro<> readPacket(Net::AsyncSocket &sock); + coro<> rP_System(Net::AsyncSocket &sock); + coro<> rP_Resource(Net::AsyncSocket &sock); + coro<> rP_Definition(Net::AsyncSocket &sock); + coro<> rP_Content(Net::AsyncSocket &sock); }; } \ No newline at end of file diff --git a/Src/Client/Vulkan/Vulkan.cpp b/Src/Client/Vulkan/Vulkan.cpp index 99ac84a..fb915cf 100644 --- a/Src/Client/Vulkan/Vulkan.cpp +++ b/Src/Client/Vulkan/Vulkan.cpp @@ -1,8 +1,13 @@ +#include #include #include #include #include #include "Vulkan.hpp" +#include "Client/ServerSession.hpp" +#include "Common/Async.hpp" +#include "Common/Net.hpp" +#include "assets.hpp" #include "imgui.h" #include #ifdef HAS_IMGUI @@ -20,10 +25,22 @@ #include #include #include +#include "VulkanRenderSession.hpp" +#include extern void LoadSymbolsVulkan(TOS::DynamicLibrary &library); -namespace TOS::VK { +namespace LV::Client::VK { + +struct ServerObj { + Server::GameServer GS; + Net::Server LS; + + ServerObj(asio::io_context &ioc) + : GS(ioc, ""), LS(ioc, [&](tcp::socket sock) -> coro<> { co_await GS.pushSocketConnect(std::move(sock)); }, 7890) + { + } +}; ByteBuffer loadPNG(std::ifstream &&read, int &width, int &height, bool &hasAlpha, bool flipOver) { @@ -55,35 +72,38 @@ ByteBuffer loadPNG(std::istream &&read, int &width, int &height, bool &hasAlpha, return buff; } -IWindowCallbackListener::~IWindowCallbackListener() = default; - -void IWindowCallbackListener::onFrameBufferResize(uint32_t width, uint32_t height) {} -void IWindowCallbackListener::onScale(float x, float y) {} -void IWindowCallbackListener::onMouseClick(int btn, int state, int mods) {} -void IWindowCallbackListener::onMousePos(double x, double y) {} -void IWindowCallbackListener::onKeyboardClick(int key, int scancode, int action, int mods) {} -void IWindowCallbackListener::onFocus(int focused) {} - -Vulkan::Vulkan(uint16_t width, uint16_t height) +Vulkan::Vulkan(asio::io_context &ioc) + : AsyncObject(ioc), GuardLock(ioc.get_executor()) { - if(width) - Screen.Width = width; - if(height) - Screen.Height = height; + Screen.Width = 1920/2; + Screen.Height = 1080/2; getSettingsNext() = getBestSettings(); + reInit(); + + addImGUIFont(LV::getResource("default.ttf")->makeView()); + Game.ImGuiInterfaces.push_back(&Vulkan::gui_MainMenu); + + Game.MainThread = std::thread([&]() { + auto useLock = Game.UseLock.lock(); + run(); + GuardLock.reset(); + + if(Game.Session) { + Game.Session->shutdown(EnumDisconnect::ByInterface); + Game.Session = nullptr; + Game.RSession = nullptr; + } + + if(Game.Server) { + Game.Server->GS.shutdown("Завершение работы из-за остановки клиента"); + Game.Server = nullptr; + } + }); } Vulkan::~Vulkan() { - WindowEventListener = nullptr; - for(size_t watchdog = 0; watchdog < 100 && isAlive(); watchdog++) - { - glfwSetWindowShouldClose(Graphics.Window, 1); - Time::sleep3(100); - } - - if(isAlive()) - LOGGER.error() << "WatchDog: Не дождались завершения потока рендера в течении 10 секунд"; + Game.UseLock.wait_no_use(); for(std::shared_ptr dependent : ROS_Dependents) dependent->free(this); @@ -96,6 +116,8 @@ Vulkan::~Vulkan() glfwDestroyWindow(Graphics.Window); Graphics.Window = nullptr; } + + Game.MainThread.join(); } void Vulkan::run() @@ -122,8 +144,29 @@ void Vulkan::run() } } - if(CallBeforeDraw) - CallBeforeDraw(this); + if(glfwWindowShouldClose(Graphics.Window)) { + NeedShutdown = true; + } + + if(Game.Session) { + ServerSession &sobj = *Game.Session; + + // Спрятать или показать курсор + { + int mode = glfwGetInputMode(Graphics.Window, GLFW_CURSOR); + if(mode == GLFW_CURSOR_HIDDEN && sobj.CursorMode != ISurfaceEventListener::EnumCursorMoveMode::MoveAndHidden) + glfwSetInputMode(Graphics.Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + else if(mode == GLFW_CURSOR_NORMAL && sobj.CursorMode != ISurfaceEventListener::EnumCursorMoveMode::Default) { + glfwSetInputMode(Graphics.Window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); + glfwSetCursorPos(Graphics.Window, Screen.Width/2., Screen.Height/2.); + } + } + + + } + + // if(CallBeforeDraw) + // CallBeforeDraw(this); glfwPollEvents(); @@ -208,8 +251,8 @@ void Vulkan::run() vkCmdSetScissor(Graphics.CommandBufferRender, 0, 1, &scissor); } - if(CallOnDraw) - CallOnDraw(this, 0, Graphics.CommandBufferRender); + // if(CallOnDraw) + // CallOnDraw(this, 0, Graphics.CommandBufferRender); vkCmdEndRenderPass(Graphics.CommandBufferRender); @@ -254,7 +297,7 @@ void Vulkan::run() { const VkClearValue clear_values[2] = { - [0] = { .color = { .float32 = { 0.2f, 0.2f, 0.4f, 1.2f }}}, + [0] = { .color = { .float32 = { 0.1f, 0.1f, 0.1f, 1.0f }}}, [1] = { .depthStencil = { 1, 0 } }, }; @@ -279,12 +322,13 @@ void Vulkan::run() ImGui_ImplVulkan_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); - #endif - if(CallOnDraw) - CallOnDraw(this, 1, Graphics.CommandBufferRender); + ImGui::SetNextWindowPos({0, 0}); + ImGui::SetNextWindowSize({(float) Screen.Width, (float) Screen.Height}); + + assert(Game.ImGuiInterfaces.size()); + (this->*Game.ImGuiInterfaces.back())(); - #ifdef HAS_IMGUI ImGui::Render(); ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), Graphics.CommandBufferRender); #endif @@ -819,45 +863,52 @@ void Vulkan::glfwCallbackOnResize(GLFWwindow *window, int width, int height) handler->freeSwapchains(); handler->buildSwapchains(); - if(handler->WindowEventListener) - handler->WindowEventListener->onFrameBufferResize(width, height); + if(handler->Game.Session) + handler->Game.Session->onResize(width, height); } } void Vulkan::glfwCallbackOnMouseButton(GLFWwindow* window, int button, int action, int mods) { Vulkan *handler = (Vulkan*) glfwGetWindowUserPointer(window); - if(handler && handler->WindowEventListener) - handler->WindowEventListener->onMouseClick(button, action, mods); + + if(handler->Game.Session) + handler->Game.Session->onCursorBtn((ISurfaceEventListener::EnumCursorBtn) button, action); } void Vulkan::glfwCallbackOnCursorPos(GLFWwindow* window, double xpos, double ypos) { Vulkan *handler = (Vulkan*) glfwGetWindowUserPointer(window); - if(handler && handler->WindowEventListener) - handler->WindowEventListener->onMousePos(xpos, ypos); + + if(handler->Game.Session) { + ServerSession &sobj = *handler->Game.Session; + if(sobj.CursorMode == ISurfaceEventListener::EnumCursorMoveMode::Default) { + sobj.onCursorPosChange((int32_t) xpos, (int32_t) ypos); + } else { + glfwSetCursorPos(handler->Graphics.Window, handler->Screen.Width/2., handler->Screen.Height/2.); + sobj.onCursorMove(xpos-handler->Screen.Width/2., handler->Screen.Height/2.-ypos); + } + } } void Vulkan::glfwCallbackOnScale(GLFWwindow* window, float xscale, float yscale) { Vulkan *handler = (Vulkan*) glfwGetWindowUserPointer(window); - if(handler && handler->WindowEventListener) - handler->WindowEventListener->onScale(xscale, yscale); } void Vulkan::glfwCallbackOnKey(GLFWwindow* window, int key, int scancode, int action, int mods) { Vulkan *handler = (Vulkan*) glfwGetWindowUserPointer(window); - if(handler && handler->WindowEventListener) - handler->WindowEventListener->onKeyboardClick(key, scancode, action, mods); + if(handler->Game.Session) + handler->Game.Session->onKeyboardBtn(key, action); } void Vulkan::glfwCallbackOnFocus(GLFWwindow* window, int focused) { Vulkan *handler = (Vulkan*) glfwGetWindowUserPointer(window); - if(handler && handler->WindowEventListener) - handler->WindowEventListener->onFocus(focused); + if(handler->Game.Session) + handler->Game.Session->onChangeFocusState(focused); } void Vulkan::checkLibrary() @@ -1066,7 +1117,7 @@ void Vulkan::checkLibrary() glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); //glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); - Graphics.Window = glfwCreateWindow(Screen.Width, Screen.Height, "Duckout", nullptr, nullptr); + Graphics.Window = glfwCreateWindow(Screen.Width, Screen.Height, "LuaVox", nullptr, nullptr); if (!Graphics.Window) { const char *error_msg; @@ -1716,12 +1767,10 @@ void Vulkan::deInitVulkan() if(Graphics.ImGuiDescPool) vkDestroyDescriptorPool(Graphics.Device, Graphics.ImGuiDescPool, nullptr); - // Удаляем SwapChain if(Graphics.Swapchain) vkDestroySwapchainKHR(Graphics.Device, Graphics.Swapchain, nullptr); - // Очистка буферов команд if(Graphics.CommandBufferData) vkFreeCommandBuffers(Graphics.Device, Graphics.Pool, 1, &Graphics.CommandBufferData); @@ -1729,7 +1778,6 @@ void Vulkan::deInitVulkan() if(Graphics.CommandBufferRender) vkFreeCommandBuffers(Graphics.Device, Graphics.Pool, 1, &Graphics.CommandBufferRender); - // Освобождение пула команд if(Graphics.Pool) vkDestroyCommandPool(Graphics.Device, Graphics.Pool, nullptr); @@ -1739,8 +1787,8 @@ void Vulkan::deInitVulkan() vkDestroyRenderPass(Graphics.Device, Graphics.RenderPass, nullptr); // Освобождение виртуального устройства - if(Graphics.Device) - vkDestroyDevice(Graphics.Device, nullptr); + //if(Graphics.Device) + // vkDestroyDevice(Graphics.Device, nullptr); } if(Graphics.Surface) @@ -1837,7 +1885,7 @@ Vulkan& Vulkan::operator<<(std::shared_ptr dependent) return *this; } -void Vulkan::addImGUIFont(const ByteBuffer &font) { +void Vulkan::addImGUIFont(std::string_view view) { ImFontConfig fontConfig; fontConfig.MergeMode = false; fontConfig.PixelSnapH = true; @@ -1845,16 +1893,121 @@ void Vulkan::addImGUIFont(const ByteBuffer &font) { fontConfig.OversampleV = 1; auto &io = ImGui::GetIO(); - uint8_t *fontPtr = new uint8_t[font.size()]; - std::copy(font.begin(), font.end(), fontPtr); + uint8_t *fontPtr = new uint8_t[view.size()]; + std::copy(view.begin(), view.end(), fontPtr); try{ - io.Fonts->AddFontFromMemoryTTF(fontPtr, font.size(), 16.0f, &fontConfig, io.Fonts->GetGlyphRangesCyrillic()); + io.Fonts->AddFontFromMemoryTTF(fontPtr, view.size(), 16.0f, &fontConfig, io.Fonts->GetGlyphRangesCyrillic()); } catch(...) { delete[] fontPtr; throw; } } +void Vulkan::gui_MainMenu() { + if(!ImGui::Begin("MainMenu", nullptr, ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove)) + return; + + static struct { + char Address[256] = "localhost", Username[256], Password[256]; + bool Cancel = false, InProgress = false; + std::string Progress; + + std::unique_ptr Socket; + + coro<> connect(asio::io_context &ioc) { + try { + std::string a(Address, strlen(Address)); + std::string u(Username, strlen(Username)); + std::string p(Password, strlen(Password)); + + tcp::socket sock = co_await Net::asyncConnectTo(a, [&](const std::string &text) { + Progress += text; + }); + + co_await Client::ServerSession::asyncAuthorizeWithServer(sock, u, p, 1, [&](const std::string &text) { + Progress += text; + }); + + Socket = co_await Client::ServerSession::asyncInitGameProtocol(ioc, std::move(sock), [&](const std::string &text) { + Progress += text; + }); + } catch(const std::exception &exc) { + Progress += "\n-> "; + Progress += exc.what(); + } + + InProgress = false; + + co_return; + } + } ConnectionProgress; + + ImGui::InputText("Address", ConnectionProgress.Address, sizeof(ConnectionProgress.Address)); + ImGui::InputText("Username", ConnectionProgress.Username, sizeof(ConnectionProgress.Username)); + ImGui::InputText("Password", ConnectionProgress.Password, sizeof(ConnectionProgress.Password), ImGuiInputTextFlags_Password); + + if(!ConnectionProgress.InProgress && !ConnectionProgress.Socket) { + if(ImGui::Button("Подключиться")) { + ConnectionProgress.InProgress = true; + ConnectionProgress.Cancel = false; + ConnectionProgress.Progress.clear(); + co_spawn(ConnectionProgress.connect(IOC)); + } + + if(!Game.Server) { + if(ImGui::Button("Запустить сервер")) { + try { + Game.Server = std::make_unique(IOC); + ConnectionProgress.Progress = "Сервер запущен на порту " + std::to_string(Game.Server->LS.getPort()); + } catch(const std::exception &exc) { + ConnectionProgress.Progress = "Не удалось запустить внутренний сервер: " + std::string(exc.what()); + } + } + } else { + if(!Game.Server->GS.isAlive()) + Game.Server = nullptr; + else if(ImGui::Button("Остановить сервер")) { + Game.Server->GS.shutdown("Сервер останавливается по запросу интерфейса"); + } + } + } + + if(ConnectionProgress.InProgress) { + if(ImGui::Button("Отмена")) + ConnectionProgress.Cancel = true; + } + + if(!ConnectionProgress.Progress.empty()) { + if(ImGui::BeginChild("Прогресс", {0, 0}, ImGuiChildFlags_Borders, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_HorizontalScrollbar)) { + ImGui::Text("Прогресс:\n%s", ConnectionProgress.Progress.c_str()); + ImGui::EndChild(); + } + } + + if(ConnectionProgress.Socket) { + std::unique_ptr sock = std::move(ConnectionProgress.Socket); + Game.RSession = std::make_unique(this); + Game.Session = std::make_unique(IOC, std::move(sock), Game.RSession.get()); + Game.RSession->setServerSession(Game.Session.get()); + Game.ImGuiInterfaces.push_back(&Vulkan::gui_ConnectedToServer); + } + + + ImGui::End(); +} + +void Vulkan::gui_ConnectedToServer() { + if(Game.Session) { + if(Game.Session->isConnected()) + return; + + Game.RSession = nullptr; + Game.Session = nullptr; + Game.ImGuiInterfaces.pop_back(); + } +} + + EnumRebuildType IVulkanDependent::needRebuild() { return EnumRebuildType::None; } IVulkanDependent::~IVulkanDependent() = default; @@ -1947,7 +2100,7 @@ Vulkan::vkInstance::~vkInstance() if(!Instance) return; - vkDestroyInstance(Instance, nullptr); + //vkDestroyInstance(Instance, nullptr); } diff --git a/Src/Client/Vulkan/Vulkan.hpp b/Src/Client/Vulkan/Vulkan.hpp index 39d325d..140f1e2 100644 --- a/Src/Client/Vulkan/Vulkan.hpp +++ b/Src/Client/Vulkan/Vulkan.hpp @@ -1,6 +1,10 @@ #pragma once +#include "Client/ServerSession.hpp" +#include "Common/Async.hpp" #include +#include +#include #include #include #include @@ -26,7 +30,10 @@ #define IMGUI_ENABLE_STB_TEXTEDIT_UNICODE -namespace TOS::VK { +namespace LV::Client::VK { + +class VulkanRenderSession; +using namespace TOS; ByteBuffer loadPNG(std::ifstream &&file, int &width, int &height, bool &hasAlpha, bool flipOver = true); ByteBuffer loadPNG(std::istream &&file, int &width, int &height, bool &hasAlpha, bool flipOver = true); @@ -49,21 +56,7 @@ struct Settings { } }; - -class IWindowCallbackListener { -public: - IWindowCallbackListener() = default; - virtual ~IWindowCallbackListener(); - - virtual void onFrameBufferResize(uint32_t width, uint32_t height); - virtual void onScale(float x, float y); - virtual void onMouseClick(int btn, int state, int mods); - virtual void onMousePos(double x, double y); - virtual void onKeyboardClick(int key, int scancode, int action, int mods); - virtual void onFocus(int focused); -}; - - +class ServerObj; class DescriptorLayout; class Pipeline; class DescriptorPool; @@ -76,7 +69,7 @@ class Buffer; Vulkan.reInit(); */ -class Vulkan { +class Vulkan : public AsyncObject { private: struct vkInstanceLayer { std::string LayerName = "nullptr", Description = "nullptr"; @@ -173,10 +166,9 @@ private: VkCommandBuffer Cmd = nullptr; VkFramebuffer FrameBuffer = nullptr; }; - - std::function CallOnDraw; - std::function CallBeforeDraw; + bool NeedShutdown = false; + asio::executor_work_guard GuardLock; public: struct { @@ -243,6 +235,16 @@ public: DrawState State = DrawState::Begin; } Screen; + struct { + DestroyLock UseLock; + std::thread MainThread; + std::unique_ptr RSession; + std::unique_ptr Session; + + std::list ImGuiInterfaces; + std::unique_ptr Server; + } Game; + private: Logger LOGGER = "Vulkan"; Settings @@ -256,7 +258,6 @@ private: std::optional LibraryVulkan; std::queue> VulkanContext; - std::shared_ptr WindowEventListener; // Объекты рисовки std::unordered_set> ROS_Dependents; @@ -298,7 +299,7 @@ private: void buildSwapchains(); public: - Vulkan(uint16_t width = 0, uint16_t height = 0); + Vulkan(asio::io_context &ioc); ~Vulkan(); Vulkan(const Vulkan&) = delete; @@ -339,12 +340,6 @@ public: Settings& getSettingsNext() { return SettingsNext; } bool isAlive() { return false; } - void start(std::function &&onDraw, std::function &&beforeDraw = {}) - { - CallOnDraw = std::move(onDraw); - CallBeforeDraw = std::move(beforeDraw); - run(); - } // Добавить обработчик перед началом рисовки кадра void beforeDraw(std::function &&callback) { @@ -356,10 +351,11 @@ public: return std::this_thread::get_id() == Graphics.ThisThread; } - void setWindowEventListener(std::shared_ptr listener) { WindowEventListener = listener; } void shutdown() { NeedShutdown = true; } + void addImGUIFont(std::string_view view); - void addImGUIFont(const ByteBuffer &font); + void gui_MainMenu(); + void gui_ConnectedToServer(); }; enum class EnumRebuildType { diff --git a/Src/Client/Vulkan/VulkanRenderSession.cpp b/Src/Client/Vulkan/VulkanRenderSession.cpp new file mode 100644 index 0000000..db7bc08 --- /dev/null +++ b/Src/Client/Vulkan/VulkanRenderSession.cpp @@ -0,0 +1,63 @@ +#include "VulkanRenderSession.hpp" + +namespace LV::Client::VK { + + +VulkanRenderSession::VulkanRenderSession(VK::Vulkan *vkInst) + : VkInst(vkInst), + MainAtlas(vkInst) +{ + assert(VkInst); +} + +VulkanRenderSession::~VulkanRenderSession() { + +} + +void VulkanRenderSession::onDefTexture(TextureId_c id, std::vector &&info) { + +} + +void VulkanRenderSession::onDefTextureLost(const std::vector &&lost) { + +} + +void VulkanRenderSession::onDefModel(ModelId_c id, std::vector &&info) { + +} + +void VulkanRenderSession::onDefModelLost(const std::vector &&lost) { + +} + +void VulkanRenderSession::onDefWorldUpdates(const std::vector &updates) { + +} + +void VulkanRenderSession::onDefVoxelUpdates(const std::vector &updates) { + +} + +void VulkanRenderSession::onDefNodeUpdates(const std::vector &updates) { + +} + +void VulkanRenderSession::onDefPortalUpdates(const std::vector &updates) { + +} + +void VulkanRenderSession::onDefEntityUpdates(const std::vector &updates) { + +} + +void VulkanRenderSession::onChunksChange(WorldId_c worldId, const std::vector &changeOrAddList, const std::vector &remove) { + +} + +void VulkanRenderSession::setCameraPos(WorldId_c worldId, Pos::Object pos, glm::quat quat) { + WorldId = worldId; + Pos = pos; + Quat = quat; +} + +} \ No newline at end of file diff --git a/Src/Client/Vulkan/VulkanRenderSession.hpp b/Src/Client/Vulkan/VulkanRenderSession.hpp new file mode 100644 index 0000000..a1667a6 --- /dev/null +++ b/Src/Client/Vulkan/VulkanRenderSession.hpp @@ -0,0 +1,43 @@ +#pragma once +#include "Client/Abstract.hpp" +#include + + +namespace LV::Client::VK { + +class VulkanRenderSession : public IRenderSession { + VK::Vulkan *VkInst; + IServerSession *ServerSession = nullptr; + + WorldId_c WorldId; + Pos::Object Pos; + glm::quat Quat; + + VK::AtlasImage MainAtlas; + std::map ServerToAtlas; + +public: + VulkanRenderSession(VK::Vulkan *vkInst); + virtual ~VulkanRenderSession(); + + void setServerSession(IServerSession *serverSession) { + ServerSession = serverSession; + assert(serverSession); + } + + virtual void onDefTexture(TextureId_c id, std::vector &&info) override; + virtual void onDefTextureLost(const std::vector &&lost) override; + virtual void onDefModel(ModelId_c id, std::vector &&info) override; + virtual void onDefModelLost(const std::vector &&lost) override; + + virtual void onDefWorldUpdates(const std::vector &updates) override; + virtual void onDefVoxelUpdates(const std::vector &updates) override; + virtual void onDefNodeUpdates(const std::vector &updates) override; + virtual void onDefPortalUpdates(const std::vector &updates) override; + virtual void onDefEntityUpdates(const std::vector &updates) override; + + virtual void onChunksChange(WorldId_c worldId, const std::vector &changeOrAddList, const std::vector &remove) override; + virtual void setCameraPos(WorldId_c worldId, Pos::Object pos, glm::quat quat) override; +}; + +} \ No newline at end of file diff --git a/Src/Common/Abstract.hpp b/Src/Common/Abstract.hpp index 233ba9e..db0fa00 100644 --- a/Src/Common/Abstract.hpp +++ b/Src/Common/Abstract.hpp @@ -32,7 +32,7 @@ struct Local16 { using Key = uint16_t; operator Key() const { - return Key(X) | (Key(Y) << 4) | (Key(Z) << 8); + return Key(uint8_t(X)) | (Key(uint8_t(Y) << 4)) | (Key(uint8_t(Z)) << 8); }; Local4_u left() const { return Local4_u{uint8_t(uint16_t(X) >> 2), uint8_t(uint16_t(Y) >> 2), uint8_t(uint16_t(Z) >> 2)}; } @@ -74,18 +74,18 @@ struct GlobalNode { using Key = uint64_t; operator Key() const { - return Key(X) | (Key(Y) << 20) | (Key(Z) << 40); + return Key(uint32_t(X)) | (Key(uint32_t(Y) << 20)) | (Key(uint32_t(Z)) << 40); }; auto operator<=>(const GlobalNode&) const = default; }; struct GlobalChunk { - int16_t X : 16, Y : 16, Z : 16; + int16_t X, Y, Z; using Key = uint64_t; operator Key() const { - return Key(X) | (Key(Y) << 16) | (Key(Z) << 32); + return Key(uint16_t(X)) | (Key(uint16_t(Y)) << 16) | (Key(uint16_t(Z)) << 32); }; auto operator<=>(const GlobalChunk&) const = default; @@ -96,7 +96,7 @@ struct GlobalRegion { using Key = uint64_t; operator Key() const { - return Key(X) | (Key(Y) << 12) | (Key(Z) << 24); + return Key(uint16_t(X)) | (Key(uint16_t(Y) << 12)) | (Key(uint16_t(Z)) << 24); }; auto operator<=>(const GlobalRegion&) const = default; @@ -118,6 +118,20 @@ struct LightPrism { uint8_t R : 2, G : 2, B : 2; }; +// Идентификаторы на стороне клиента +using TextureId_c = uint16_t; +using SoundId_c = uint16_t; +using ModelId_c = uint16_t; + +using DefWorldId_c = uint8_t; +using DefVoxelId_c = uint16_t; +using DefNodeId_c = uint16_t; +using DefPortalId_c = uint8_t; +using WorldId_c = uint8_t; +using PortalId_c = uint8_t; +using DefEntityId_c = uint16_t; +using EntityId_c = uint16_t; + } diff --git a/Src/Common/Async.hpp b/Src/Common/Async.hpp index faf4085..0e96959 100644 --- a/Src/Common/Async.hpp +++ b/Src/Common/Async.hpp @@ -112,7 +112,7 @@ public: return; std::atomic_bool flag = false; - Deadline.async_wait([&](boost::system::error_code errc) { flag.store(true); }); + Deadline.async_wait([&](boost::system::error_code errc) { flag.store(true); flag.notify_all(); }); lock.unlock(); flag.wait(false); } @@ -129,7 +129,7 @@ public: return; std::atomic_bool flag = false; - Deadline.async_wait([&](boost::system::error_code errc) { flag.store(true); }); + Deadline.async_wait([&](boost::system::error_code errc) { flag.store(true); flag.notify_all(); }); lock.unlock(); flag.wait(false); } diff --git a/Src/Common/Lockable.hpp b/Src/Common/Lockable.hpp index 10e2e53..f8d6005 100644 --- a/Src/Common/Lockable.hpp +++ b/Src/Common/Lockable.hpp @@ -110,10 +110,12 @@ public: : Lock(lock) { lock.UseCount++; + lock.UseCount.notify_all(); } ~Guard() { Lock.UseCount--; + Lock.UseCount.notify_all(); } private: diff --git a/Src/Common/Net.cpp b/Src/Common/Net.cpp index 21de8e1..134f2a9 100644 --- a/Src/Common/Net.cpp +++ b/Src/Common/Net.cpp @@ -1,6 +1,7 @@ #include "Net.hpp" #include #include +#include namespace LV::Net { @@ -17,15 +18,14 @@ bool Server::isStopped() { void Server::stop() { NeedClose = true; + NeedClose.notify_all(); if(Acceptor.is_open()) Acceptor.close(); } void Server::wait() { - if(!IsAlive) - return; - - Lock.wait(); + while(bool val = IsAlive) + IsAlive.wait(val); } coro Server::async_wait() { @@ -45,6 +45,7 @@ coro Server::run() { } IsAlive.store(false); + IsAlive.notify_all(); Lock.cancel(); } @@ -56,6 +57,7 @@ AsyncSocket::~AsyncSocket() { SendPackets.Context->NeedShutdown = true; SendPackets.SenderGuard.cancel(); + WorkDeadline.cancel(); } void AsyncSocket::pushPackets(std::vector *simplePackets, std::vector *smartPackets) { @@ -135,6 +137,10 @@ coro<> AsyncSocket::read(std::byte *data, uint32_t size) { } } +void AsyncSocket::closeRead() { + Socket.shutdown(boost::asio::socket_base::shutdown_receive); +} + coro<> AsyncSocket::waitForSend() { asio::deadline_timer waiter(IOC); @@ -249,8 +255,7 @@ coro asyncConnectTo(const std::string address, std::function asyncConnectTo(const std::string address, std::function *simplePackets, std::vector *smartPackets = nullptr); + + void pushPacket(Packet &&simplePacket) { + std::vector out(1); + out[0] = std::move(simplePacket); + pushPackets(&out); + } std::string getError() const; bool isAlive() const; coro<> read(std::byte *data, uint32_t size); + void closeRead(); template or std::is_same_v, int> = 0> coro read() { diff --git a/Src/Common/Packets.hpp b/Src/Common/Packets.hpp index 45afe1b..10892be 100644 --- a/Src/Common/Packets.hpp +++ b/Src/Common/Packets.hpp @@ -6,8 +6,14 @@ namespace LV { -namespace ToServer { +enum struct EnumDisconnect { + ByInterface, + CriticalError, + ProtocolError +}; +namespace ToServer { + struct PacketQuat { uint8_t Data[5]; @@ -51,6 +57,17 @@ struct PacketQuat { */ +// Первый уровень +enum struct L1 : uint8_t { + System, +}; + +// Второй уровень +enum struct L2System : uint8_t { + InitEnd, + Disconnect +}; + } namespace ToClient { diff --git a/Src/Server/Abstract.hpp b/Src/Server/Abstract.hpp index 65cd43d..44f50a4 100644 --- a/Src/Server/Abstract.hpp +++ b/Src/Server/Abstract.hpp @@ -8,20 +8,6 @@ namespace LV::Server { -// Идентификаторы на стороне клиента -using TextureId_c = uint16_t; -using SoundId_c = uint16_t; -using ModelId_c = uint16_t; - -using DefWorldId_c = uint8_t; -using WorldId_c = uint8_t; -using VoxelId_c = uint16_t; -using NodeId_c = uint16_t; -using DefPortalId_c = uint8_t; -using PortalId_c = uint8_t; -using DefEntityId_c = uint16_t; -using EntityId_c = uint16_t; - using ResourceId_t = uint32_t; // Двоичные данные diff --git a/Src/Server/GameServer.cpp b/Src/Server/GameServer.cpp index 72dfaf5..8d897f4 100644 --- a/Src/Server/GameServer.cpp +++ b/Src/Server/GameServer.cpp @@ -1,6 +1,7 @@ #include "GameServer.hpp" #include "Common/Abstract.hpp" #include "Common/Net.hpp" +#include "Common/Packets.hpp" #include "Server/Abstract.hpp" #include "Server/ContentEventController.hpp" #include @@ -248,7 +249,7 @@ void GameServer::run() { if(IsGoingShutdown) { // Отключить игроков for(std::unique_ptr &cec : Game.CECs) { - cec->Remote->shutdown(ShutdownReason); + cec->Remote->shutdown(EnumDisconnect::ByInterface, ShutdownReason); } // Сохранить данные @@ -259,7 +260,7 @@ void GameServer::run() { auto lock = External.NewConnectedPlayers.lock_write(); for(std::unique_ptr &client : *lock) { - client->shutdown(ShutdownReason); + client->shutdown(EnumDisconnect::ByInterface, ShutdownReason); } bool hasNewConnected = !lock->empty(); @@ -361,6 +362,14 @@ void GameServer::stepPlayers() { for(std::unique_ptr &cec : Game.CECs) { // Убрать отключившихся if(!cec->Remote->isConnected()) { + for(auto wPair : cec->SubscribedRegions) { + auto wIter = Expanse.Worlds.find(wPair.first); + if(wIter == Expanse.Worlds.end()) + continue; + + wIter->second->onCEC_RegionsLost(cec.get(), wPair.second); + } + cec.reset(); } diff --git a/Src/Server/GameServer.hpp b/Src/Server/GameServer.hpp index 2144eec..35f012c 100644 --- a/Src/Server/GameServer.hpp +++ b/Src/Server/GameServer.hpp @@ -114,7 +114,8 @@ public: void shutdown(const std::string reason) { - ShutdownReason = reason; + if(ShutdownReason.empty()) + ShutdownReason = reason; IsGoingShutdown = true; } diff --git a/Src/Server/RemoteClient.cpp b/Src/Server/RemoteClient.cpp index 92ac15d..1af42a2 100644 --- a/Src/Server/RemoteClient.cpp +++ b/Src/Server/RemoteClient.cpp @@ -14,7 +14,11 @@ namespace LV::Server { RemoteClient::~RemoteClient() { - shutdown("~RemoteClient()"); + shutdown(EnumDisconnect::ByInterface, "~RemoteClient()"); + if(Socket.isAlive()) { + Socket.closeRead(); + } + UseLock.wait_no_use(); } @@ -23,7 +27,7 @@ coro<> RemoteClient::run() { try { while(!IsGoingShutdown && IsConnected) { - co_await Socket.read(); + co_await readPacket(Socket); } } catch(const std::exception &exc) { if(const auto *errc = dynamic_cast(&exc); @@ -40,7 +44,7 @@ coro<> RemoteClient::run() { co_return; } -void RemoteClient::shutdown(const std::string reason) { +void RemoteClient::shutdown(EnumDisconnect type, const std::string reason) { if(IsGoingShutdown) return; @@ -48,7 +52,17 @@ void RemoteClient::shutdown(const std::string reason) { NextPacket << (uint8_t) ToClient::L1::System << (uint8_t) ToClient::L2System::Disconnect - << reason; + << (uint8_t) type << reason; + + std::string info; + if(type == EnumDisconnect::ByInterface) + info = "по запросу интерфейса " + reason; + else if(type == EnumDisconnect::CriticalError) + info = "на сервере произошла критическая ошибка " + reason; + else if(type == EnumDisconnect::ProtocolError) + info = "ошибка протокола (сервер) " + reason; + + LOG.info() << "Игрок '" << Username << "' отключился " << info; } @@ -70,7 +84,7 @@ void RemoteClient::prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::GlobalChunk std::unordered_set NeedVoxelsSet(NeedVoxels.begin(), NeedVoxels.end()); // Собираем информацию о конвертации идентификаторов - std::unordered_map LocalRemapper; + std::unordered_map LocalRemapper; for(DefVoxelId_t vId : NeedVoxelsSet) { LocalRemapper[vId] = ResRemap.DefVoxels.toClient(vId); } @@ -87,7 +101,7 @@ void RemoteClient::prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::GlobalChunk // Определение больше не используется ResUses.DefVoxel.erase(ResUses.DefVoxel.find(id)); - VoxelId_c cId = ResRemap.DefVoxels.erase(id); + DefVoxelId_c cId = ResRemap.DefVoxels.erase(id); // TODO: отправить пакет потери идентификатора LOG.debug() << "Определение вокселя потеряно: " << id << " -> " << cId; } @@ -99,7 +113,7 @@ void RemoteClient::prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::GlobalChunk if(++ResUses.DefVoxel[id] == 1) { // Определение только появилось NextRequest.NewVoxels.push_back(id); - VoxelId_c cId = ResRemap.DefVoxels.toClient(id); + DefVoxelId_c cId = ResRemap.DefVoxels.toClient(id); LOG.debug() << "Новое определение вокселя: " << id << " -> " << cId; } } @@ -108,24 +122,23 @@ void RemoteClient::prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::GlobalChunk prevSet = std::move(nextSet); } - // TODO: отправить новую информацию о расположении вокселей - LOG.debug() << "Новый чанк: " << worldId << " / " << chunkPos.X << ":" << chunkPos.Y << ":" << chunkPos.Z; - // Packet Id - // NextPacket << uint16_t(0); - // NextPacket << wcId << Pos::GlobalChunk::Key(chunkPos); - // NextPacket << uint16_t(voxels.size()); + LOG.debug() << "Воксели чанка: " << worldId << " / " << chunkPos.X << ":" << chunkPos.Y << ":" << chunkPos.Z; - // for(const VoxelCube &cube : voxels) { - // NextPacket << LocalRemapper[cube.VoxelId] - // << cube.Left.X << cube.Left.Y << cube.Left.Z - // << cube.Right.X << cube.Right.Y << cube.Right.Z; - // } + NextPacket << (uint8_t) ToClient::L1::Content + << (uint8_t) ToClient::L2Content::ChunkVoxels << wcId + << Pos::GlobalChunk::Key(chunkPos); + NextPacket << uint16_t(voxels.size()); + // TODO: + for(const VoxelCube &cube : voxels) { + NextPacket << LocalRemapper[cube.VoxelId] + << cube.Left.X << cube.Left.Y << cube.Left.Z + << cube.Right.X << cube.Right.Y << cube.Right.Z; + } } void RemoteClient::prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::unordered_map &nodes) { - // Перебиндить идентификаторы нод } @@ -144,7 +157,7 @@ void RemoteClient::prepareChunkRemove(WorldId_t worldId, Pos::GlobalChunk chunkP // Определение больше не используется ResUses.DefVoxel.erase(ResUses.DefVoxel.find(id)); - VoxelId_c cId = ResRemap.DefVoxels.erase(id); + DefVoxelId_c cId = ResRemap.DefVoxels.erase(id); // TODO: отправить пакет потери идентификатора LOG.debug() << "Определение вокселя потеряно: " << id << " -> " << cId; } @@ -154,7 +167,7 @@ void RemoteClient::prepareChunkRemove(WorldId_t worldId, Pos::GlobalChunk chunkP WorldId_c cwId = ResRemap.Worlds.toClient(worldId); NextPacket << (uint8_t) ToClient::L1::Content << (uint8_t) ToClient::L2Content::RemoveChunk - << cwId << chunkPos.X << chunkPos.Y << chunkPos.Z; + << cwId << Pos::GlobalChunk::Key(chunkPos); } void RemoteClient::prepareWorldNew(WorldId_t worldId, World* world) @@ -166,7 +179,7 @@ void RemoteClient::prepareWorldNew(WorldId_t worldId, World* world) DefWorldId_c cdId = ResRemap.DefWorlds.toClient(res.DefId); NextRequest.NewWorlds.push_back(res.DefId); - LOG.debug() << "Новое определение мира: " << res.DefId << " -> " << cdId; + LOG.debug() << "Новое определение мира: " << res.DefId << " -> " << int(cdId); NextPacket << (uint8_t) ToClient::L1::Definition << (uint8_t) ToClient::L2Definition::World << cdId; @@ -468,7 +481,7 @@ void RemoteClient::informateDefVoxel(const std::unordered_map if(!ResUses.DefNode.contains(sId)) continue; - NodeId_c cId = ResRemap.DefNodes.toClient(sId); + DefNodeId_c cId = ResRemap.DefNodes.toClient(sId); NextPacket << (uint8_t) ToClient::L1::Definition << (uint8_t) ToClient::L2Definition::Node @@ -521,6 +534,46 @@ void RemoteClient::informateDefPortals(const std::unordered_map RemoteClient::readPacket(Net::AsyncSocket &sock) { + uint8_t first = co_await sock.read(); + + switch((ToServer::L1) first) { + case ToServer::L1::System: co_await rP_System(sock); co_return; + default: + protocolError(); + } +} + +coro<> RemoteClient::rP_System(Net::AsyncSocket &sock) { + uint8_t second = co_await sock.read(); + + switch((ToServer::L2System) second) { + case ToServer::L2System::InitEnd: + + co_return; + case ToServer::L2System::Disconnect: + { + EnumDisconnect type = (EnumDisconnect) co_await sock.read(); + shutdown(EnumDisconnect::ByInterface, "Вы были отключены от игры"); + std::string reason; + if(type == EnumDisconnect::CriticalError) + reason = ": Критическая ошибка"; + else + reason = ": Ошибка протокола (клиент)"; + + LOG.info() << "Игрок '" << Username << "' отключился" << reason; + + co_return; + } + default: + protocolError(); + } +} + void RemoteClient::incrementBinary(std::unordered_set &textures, std::unordered_set &sounds, std::unordered_set &models) { diff --git a/Src/Server/RemoteClient.hpp b/Src/Server/RemoteClient.hpp index 333671a..af5c615 100644 --- a/Src/Server/RemoteClient.hpp +++ b/Src/Server/RemoteClient.hpp @@ -4,6 +4,7 @@ #include #include #include "Abstract.hpp" +#include "Common/Packets.hpp" #include "Server/ContentEventController.hpp" #include #include @@ -249,8 +250,8 @@ class RemoteClient { SCSKeyRemapper BinModels; SCSKeyRemapper DefWorlds; - SCSKeyRemapper DefVoxels; - SCSKeyRemapper DefNodes; + SCSKeyRemapper DefVoxels; + SCSKeyRemapper DefNodes; SCSKeyRemapper DefPortals; SCSKeyRemapper DefEntityes; @@ -275,7 +276,7 @@ public: ~RemoteClient(); coro<> run(); - void shutdown(const std::string reason); + void shutdown(EnumDisconnect type, const std::string reason); bool isConnected() { return IsConnected; } void pushPackets(std::vector *simplePackets, std::vector *smartPackets = nullptr) { @@ -330,6 +331,10 @@ public: void informateDefPortals(const std::unordered_map &portals); private: + void protocolError(); + coro<> readPacket(Net::AsyncSocket &sock); + coro<> rP_System(Net::AsyncSocket &sock); + void incrementBinary(std::unordered_set &textures, std::unordered_set &sounds, std::unordered_set &models); void decrementBinary(std::unordered_set &textures, std::unordered_set &sounds, diff --git a/Src/assets.cpp b/Src/assets.cpp index bfa11ad..06d9fa0 100644 --- a/Src/assets.cpp +++ b/Src/assets.cpp @@ -9,7 +9,7 @@ extern std::unordered_map> _binary_assets_symbols; namespace fs = std::filesystem; -namespace AL { +namespace LV { Resource::Resource() = default; Resource::~Resource() = default; diff --git a/Src/assets.hpp b/Src/assets.hpp index 6c500f4..b2bc5f5 100644 --- a/Src/assets.hpp +++ b/Src/assets.hpp @@ -3,7 +3,7 @@ #include #include -namespace AL { +namespace LV { namespace detail { struct membuf : std::streambuf { diff --git a/Src/main.cpp b/Src/main.cpp index f4ae01e..e35abcc 100644 --- a/Src/main.cpp +++ b/Src/main.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -9,6 +10,7 @@ #include #include "Client/ServerSession.hpp" #include "Common/Net.hpp" +#include "Common/Packets.hpp" #include "Server/GameServer.hpp" #include @@ -16,14 +18,14 @@ namespace LV { using namespace TOS; +std::unique_ptr session; + coro<> runClient(asio::io_context &ioc, uint16_t port) { try { tcp::socket sock = co_await Net::asyncConnectTo("localhost:"+std::to_string(port)); co_await Client::ServerSession::asyncAuthorizeWithServer(sock, "DrSocalkwe3n", "1password2", 1); std::unique_ptr asock = co_await Client::ServerSession::asyncInitGameProtocol(ioc, std::move(sock)); - asio::deadline_timer timer(ioc); - timer.expires_from_now(boost::posix_time::seconds(1)); - co_await timer.async_wait(); + session = std::make_unique(ioc, std::move(asock), nullptr); } catch(const std::exception &exc) { std::cout << exc.what() << std::endl; } @@ -31,33 +33,41 @@ coro<> runClient(asio::io_context &ioc, uint16_t port) { int main() { - VK::Vulkan VkInst; - VkInst.getSettingsNext() = VkInst.getBestSettings(); - VkInst.reInit(); - - auto ot = std::async([&](){ - VkInst.start([&](VK::Vulkan *instance, int subpass, VkCommandBuffer &renderCmd) - { - }); - }); - // LuaVox asio::io_context ioc; - Server::GameServer gs(ioc, ""); - - Net::Server server(ioc, [&](tcp::socket sock) -> coro<> { - server.stop(); - co_await gs.pushSocketConnect(std::move(sock)); - }, 6666); - - std::cout << server.getPort() << std::endl; - - asio::co_spawn(ioc, runClient(ioc, server.getPort()), asio::detached); - + LV::Client::VK::Vulkan vkInst(ioc); ioc.run(); - VkInst.shutdown(); + + // Server::GameServer gs(ioc, ""); + + // Net::Server server(ioc, [&](tcp::socket sock) -> coro<> { + // server.stop(); + // co_await gs.pushSocketConnect(std::move(sock)); + // }, 6666); + + // std::cout << server.getPort() << std::endl; + + // asio::co_spawn(ioc, runClient(ioc, server.getPort()), asio::detached); + + + // auto ot = std::async([&](){ + // VkInst.start([&](VK::Vulkan *instance, int subpass, VkCommandBuffer &renderCmd) + // { + // if(glfwWindowShouldClose(VkInst.Graphics.Window) || (session && !session->isConnected())) { + // VkInst.shutdown(); + + // if(glfwWindowShouldClose(VkInst.Graphics.Window) && session) + // session->shutdown(EnumDisconnect::ByInterface); + // } + // }); + + // session = nullptr; + // }); + + // ioc.run(); + // VkInst.shutdown(); return 0; } diff --git a/Work/assets/default.ttf b/Work/assets/default.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3c7ec0fabcd56236869311bfc5a3664e94864842 GIT binary patch literal 111816 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≧!c%$K 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 literal 0 HcmV?d00001 diff --git a/Work/assets/default2.ttf b/Work/assets/default2.ttf new file mode 100644 index 0000000000000000000000000000000000000000..05ded64d008f2f4715049f3f2bc2b43bea1534b1 GIT binary patch literal 71608 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 ML@ECx!O>{`AF&`Ui2wiq literal 0 HcmV?d00001 diff --git a/Work/imgui.ini b/Work/imgui.ini index 9930887..cb4f8f5 100644 --- a/Work/imgui.ini +++ b/Work/imgui.ini @@ -1,4 +1,8 @@ [Window][Debug##Default] -Pos=60,60 +Pos=0,0 Size=400,400 +[Window][MainMenu] +Pos=0,0 +Size=960,540 +