diff --git a/Src/Client/ServerSession.cpp b/Src/Client/ServerSession.cpp index d173c4f..67f5c4c 100644 --- a/Src/Client/ServerSession.cpp +++ b/Src/Client/ServerSession.cpp @@ -131,6 +131,7 @@ coro> ServerSession::asyncInitGameProtocol(asi void ServerSession::shutdown(EnumDisconnect type) { IsGoingShutdown = true; + Socket->closeRead(); Net::Packet packet; packet << (uint8_t) ToServer::L1::System << (uint8_t) ToServer::L2System::Disconnect @@ -206,11 +207,11 @@ coro<> ServerSession::run() { 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; - } + // if(const auto *errc = dynamic_cast(&exc); + // errc && errc->code() == boost::asio::error::operation_aborted) + // { + // co_return; + // } TOS::Logger("ServerSession").warn() << exc.what(); } @@ -387,7 +388,7 @@ coro<> ServerSession::rP_Content(Net::AsyncSocket &sock) { cube.Right.Z = co_await sock.read(); } - auto packet = std::make_unique( + PP_Content_ChunkVoxels *packet = new PP_Content_ChunkVoxels( ToClient::L1::Content, (uint8_t) ToClient::L2Content::ChunkVoxels, wcId, @@ -395,7 +396,7 @@ coro<> ServerSession::rP_Content(Net::AsyncSocket &sock) { std::move(cubes) ); - while(!NetInputPackets.push(std::move(packet))); + while(!NetInputPackets.push(packet)); LOG.info() << "Приняты воксели чанка " << int(wcId) << " / " << pos.X << ":" << pos.Y << ":" << pos.Z << " Вокселей " << cubes.size(); diff --git a/Src/Client/ServerSession.hpp b/Src/Client/ServerSession.hpp index 4f19fe5..08b1d7f 100644 --- a/Src/Client/ServerSession.hpp +++ b/Src/Client/ServerSession.hpp @@ -35,7 +35,7 @@ class ServerSession : public AsyncObject, public IServerSession, public ISurface glm::quat Quat; } Camera; - boost::lockfree::spsc_queue> NetInputPackets; + boost::lockfree::spsc_queue NetInputPackets; // glm::vec3 PYR = glm::vec3(0), PYR_Offset = glm::vec3(0); @@ -62,7 +62,7 @@ public: void shutdown(EnumDisconnect type); bool isConnected() { - return IsConnected; + return Socket->isAlive() && IsConnected; } void waitShutdown() { diff --git a/Src/Client/Vulkan/Vulkan.cpp b/Src/Client/Vulkan/Vulkan.cpp index f0c6e71..b697f6b 100644 --- a/Src/Client/Vulkan/Vulkan.cpp +++ b/Src/Client/Vulkan/Vulkan.cpp @@ -80,7 +80,6 @@ Vulkan::Vulkan(asio::io_context &ioc) getSettingsNext() = getBestSettings(); reInit(); - addImGUIFont(LV::getResource("default.ttf")->makeView()); Game.ImGuiInterfaces.push_back(&Vulkan::gui_MainMenu); Game.MainThread = std::thread([&]() { @@ -93,6 +92,7 @@ Vulkan::Vulkan(asio::io_context &ioc) Vulkan::~Vulkan() { Game.UseLock.wait_no_use(); + Game.MainThread.join(); for(std::shared_ptr dependent : ROS_Dependents) dependent->free(this); @@ -105,8 +105,6 @@ Vulkan::~Vulkan() glfwDestroyWindow(Graphics.Window); Graphics.Window = nullptr; } - - Game.MainThread.join(); } void Vulkan::run() @@ -122,9 +120,7 @@ void Vulkan::run() double prevTime = glfwGetTime(); - while(!NeedShutdown - || (Game.Session && Game.Session->isConnected()) - || (Game.Server && Game.Server->GS.isAlive())) + while(!NeedShutdown) { float dTime = glfwGetTime()-prevTime; prevTime = glfwGetTime(); @@ -142,13 +138,16 @@ void Vulkan::run() if(!NeedShutdown && glfwWindowShouldClose(Graphics.Window)) { NeedShutdown = true; - if(Game.Session) { + if(Game.Session) Game.Session->shutdown(EnumDisconnect::ByInterface); - } if(Game.Server) { Game.Server->GS.shutdown("Завершение работы из-за остановки клиента"); } + + Game.RSession = nullptr; + Game.Session = nullptr; + Game.Server = nullptr; } if(Game.Session) { @@ -428,12 +427,6 @@ void Vulkan::run() vkDestroySemaphore(Graphics.Device, SemaphoreImageAcquired, nullptr); vkDestroySemaphore(Graphics.Device, SemaphoreDrawComplete, nullptr); - - Graphics.ThisThread = std::thread::id(); - - Game.Session = nullptr; - Game.RSession = nullptr; - Game.Server = nullptr; } void Vulkan::glfwCallbackError(int error, const char *description) @@ -1856,6 +1849,7 @@ void Vulkan::reInit() { checkLibrary(); initNextSettings(); + addImGUIFont(LV::getResource("default.ttf")->makeView()); } bool Vulkan::needFullVulkanRebuild() @@ -1899,12 +1893,15 @@ void Vulkan::addImGUIFont(std::string_view view) { fontConfig.OversampleV = 1; auto &io = ImGui::GetIO(); - uint8_t *fontPtr = new uint8_t[view.size()]; + uint8_t *fontPtr = (uint8_t*) malloc(view.size()); + if(!fontPtr) + MAKE_ERROR("Not enough memory"); + std::copy(view.begin(), view.end(), fontPtr); try{ io.Fonts->AddFontFromMemoryTTF(fontPtr, view.size(), 16.0f, &fontConfig, io.Fonts->GetGlyphRangesCyrillic()); } catch(...) { - delete[] fontPtr; + free(fontPtr); throw; } } diff --git a/Src/Common/Net.cpp b/Src/Common/Net.cpp index 134f2a9..377ba84 100644 --- a/Src/Common/Net.cpp +++ b/Src/Common/Net.cpp @@ -1,7 +1,9 @@ #include "Net.hpp" #include #include +#include #include +#include namespace LV::Net { @@ -116,7 +118,8 @@ std::string AsyncSocket::getError() const { bool AsyncSocket::isAlive() const { return !SendPackets.Context->NeedShutdown - && !SendPackets.Context->RunSendShutdowned; + && !SendPackets.Context->RunSendShutdowned + && Socket.is_open(); } coro<> AsyncSocket::read(std::byte *data, uint32_t size) { @@ -138,7 +141,10 @@ coro<> AsyncSocket::read(std::byte *data, uint32_t size) { } void AsyncSocket::closeRead() { - Socket.shutdown(boost::asio::socket_base::shutdown_receive); + if(Socket.is_open() && !ReadShutdowned) { + ReadShutdowned = true; + Socket.shutdown(boost::asio::socket_base::shutdown_receive); + } } coro<> AsyncSocket::waitForSend() { diff --git a/Src/Common/Net.hpp b/Src/Common/Net.hpp index e01b53c..1e0e326 100644 --- a/Src/Common/Net.hpp +++ b/Src/Common/Net.hpp @@ -190,6 +190,7 @@ protected: class AsyncSocket : public AsyncObject { NetPool::Array<32> RecvBuffer, SendBuffer; size_t RecvPos = 0, RecvSize = 0, SendSize = 0; + bool ReadShutdowned = false; tcp::socket Socket; static constexpr uint32_t diff --git a/Src/main.cpp b/Src/main.cpp index e35abcc..8dc7d82 100644 --- a/Src/main.cpp +++ b/Src/main.cpp @@ -1,74 +1,19 @@ -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include "Client/ServerSession.hpp" -#include "Common/Net.hpp" -#include "Common/Packets.hpp" -#include "Server/GameServer.hpp" +#include #include 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)); - session = std::make_unique(ioc, std::move(asock), nullptr); - } catch(const std::exception &exc) { - std::cout << exc.what() << std::endl; - } -} - int main() { // LuaVox - asio::io_context ioc; LV::Client::VK::Vulkan vkInst(ioc); ioc.run(); - // 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; }