From 1bf897b3d1864c92a661043409d9e6da6271f4d9 Mon Sep 17 00:00:00 2001 From: DrSocalkwe3n Date: Sat, 30 Aug 2025 03:12:18 +0600 Subject: [PATCH] * --- Src/Client/Abstract.hpp | 4 +- Src/Client/ServerSession.cpp | 581 +++++++++++++++++++---------------- Src/Client/ServerSession.hpp | 40 ++- Src/Server/RemoteClient.cpp | 2 +- 4 files changed, 350 insertions(+), 277 deletions(-) diff --git a/Src/Client/Abstract.hpp b/Src/Client/Abstract.hpp index 44cd918..b3ba8d1 100644 --- a/Src/Client/Abstract.hpp +++ b/Src/Client/Abstract.hpp @@ -76,9 +76,9 @@ public: std::unordered_map> Profiles_Lost; // Новые или изменённые чанки - std::unordered_map> Chunks_ChangeOrAdd; + std::unordered_map> Chunks_ChangeOrAdd; // Более не отслеживаемые регионы - std::unordered_map> Chunks_Lost; + std::unordered_map> Chunks_Lost; }; public: diff --git a/Src/Client/ServerSession.cpp b/Src/Client/ServerSession.cpp index 9405e61..e79331f 100644 --- a/Src/Client/ServerSession.cpp +++ b/Src/Client/ServerSession.cpp @@ -1,5 +1,6 @@ #include "ServerSession.hpp" #include "Client/Abstract.hpp" +#include "Client/AssetsManager.hpp" #include "Common/Abstract.hpp" #include "Common/Net.hpp" #include "TOSAsync.hpp" @@ -21,7 +22,7 @@ namespace LV::Client { ServerSession::ServerSession(asio::io_context &ioc, std::unique_ptr&& socket) - : IAsyncDestructible(ioc), Socket(std::move(socket)), NetInputPackets(1024) + : IAsyncDestructible(ioc), Socket(std::move(socket)) //, NetInputPackets(1024) { assert(Socket.get()); @@ -40,78 +41,6 @@ coro<> ServerSession::asyncDestructor() { - - -ParsedPacket::~ParsedPacket() = default; - -struct PP_Content_ChunkVoxels : public ParsedPacket { - WorldId_t Id; - Pos::GlobalChunk Pos; - std::vector Cubes; - - PP_Content_ChunkVoxels(WorldId_t id, Pos::GlobalChunk pos, std::vector &&cubes) - : ParsedPacket(ToClient::L1::Content, (uint8_t) ToClient::L2Content::ChunkVoxels), Id(id), Pos(pos), Cubes(std::move(cubes)) - {} -}; - -struct PP_Content_ChunkNodes : public ParsedPacket { - WorldId_t Id; - Pos::GlobalChunk Pos; - std::array Nodes; - - PP_Content_ChunkNodes(WorldId_t id, Pos::GlobalChunk pos) - : ParsedPacket(ToClient::L1::Content, (uint8_t) ToClient::L2Content::ChunkNodes), Id(id), Pos(pos) - { - } -}; - -struct PP_Content_RegionRemove : public ParsedPacket { - WorldId_t Id; - Pos::GlobalRegion Pos; - - PP_Content_RegionRemove(WorldId_t id, Pos::GlobalRegion pos) - : ParsedPacket(ToClient::L1::Content, (uint8_t) ToClient::L2Content::RemoveRegion), Id(id), Pos(pos) - {} -}; - -struct PP_Definition_Voxel : public ParsedPacket { - DefVoxelId Id; - DefVoxel_t Def; - - PP_Definition_Voxel(DefVoxelId id, DefVoxel_t def) - : ParsedPacket(ToClient::L1::Definition, (uint8_t) ToClient::L2Definition::Voxel), - Id(id), Def(def) - {} -}; - -struct PP_Definition_FreeVoxel : public ParsedPacket { - DefVoxelId Id; - - PP_Definition_FreeVoxel(DefVoxelId id) - : ParsedPacket(ToClient::L1::Definition, (uint8_t) ToClient::L2Definition::FreeVoxel), - Id(id) - {} -}; - -struct PP_Definition_Node : public ParsedPacket { - DefNodeId Id; - DefNode_t Def; - - PP_Definition_Node(DefNodeId id, DefNode_t def) - : ParsedPacket(ToClient::L1::Definition, (uint8_t) ToClient::L2Definition::Node), - Id(id), Def(def) - {} -}; - -struct PP_Definition_FreeNode : public ParsedPacket { - DefNodeId Id; - - PP_Definition_FreeNode(DefNodeId id) - : ParsedPacket(ToClient::L1::Definition, (uint8_t) ToClient::L2Definition::FreeNode), - Id(id) - {} -}; - using namespace TOS; ServerSession::~ServerSession() { @@ -347,7 +276,36 @@ void ServerSession::update(GlobalTime gTime, float dTime) { AM->pushResources(std::move(resources)); } + // Получить ресурсы с AssetsManager + { + std::vector>> resources = AM->pullReads(); + std::vector needRequest; + for(auto& [key, res] : resources) { + if(!res) { + // Проверить не был ли уже отправлен запрос на получение этого хеша + auto iter = std::lower_bound(AsyncContext.AlreadyLoading.begin(), AsyncContext.AlreadyLoading.end(), res->hash()); + if(iter == AsyncContext.AlreadyLoading.end()) { + AsyncContext.AlreadyLoading.insert(iter, res->hash()); + needRequest.push_back(res->hash()); + } + } else { + AsyncContext.LoadedResources.emplace_back(key, *res); + } + } + + if(!needRequest.empty()) { + assert(needRequest.size() < (1 << 16)); + + Net::Packet p; + p << (uint8_t) ToServer::L1::System << (uint8_t) ToServer::L2System::ResourceRequest; + p << (uint16_t) needRequest.size(); + for(const Hash_t& hash : needRequest) + p.write((const std::byte*) hash.data(), 32); + + Socket->pushPacket(std::move(p)); + } + } // Разбираемся с полученными меж тактами привязками ресурсов if(!AsyncContext.AssetsBinds.get_read().empty()) { @@ -436,8 +394,6 @@ void ServerSession::update(GlobalTime gTime, float dTime) { } } - // Assets.ExistBinds[(int) bind.Type].insert(bind.Id); - // Под рукой нет ресурса, отправим на проверку в AssetsManager if(needQuery) { AsyncContext.ResourceWait[(int) bind.Type][bind.Domain].emplace_back(bind.Key, bind.Hash); @@ -448,6 +404,8 @@ void ServerSession::update(GlobalTime gTime, float dTime) { // Отправляем запрос на получение ресурсов if(!needToLoad.empty()) AM->pushReads(std::move(needToLoad)); + + AsyncContext.Binds.push_back(std::move(abc)); } if(!AsyncContext.TickSequence.get_read().empty()) { @@ -456,11 +414,274 @@ void ServerSession::update(GlobalTime gTime, float dTime) { if(RS) RS->prepareTickSync(); + std::vector ticks = std::move(*AsyncContext.TickSequence.lock()); + IRenderSession::TickSyncData result; // Перевариваем данные по тактам + // Профили + std::unordered_map profile_Voxel_AddOrChange; + std::vector profile_Voxel_Lost; + std::unordered_map profile_Node_AddOrChange; + std::vector profile_Node_Lost; + std::unordered_map profile_World_AddOrChange; + std::vector profile_World_Lost; + std::unordered_map profile_Portal_AddOrChange; + std::vector profile_Portal_Lost; + std::unordered_map profile_Entity_AddOrChange; + std::vector profile_Entity_Lost; + std::unordered_map profile_Item_AddOrChange; + std::vector profile_Item_Lost; + + { + for(TickData& data : ticks) { + { + for(auto& [id, profile] : data.Profile_Voxel_AddOrChange) { + auto iter = std::lower_bound(profile_Voxel_Lost.begin(), profile_Voxel_Lost.end(), id); + if(iter != profile_Voxel_Lost.end()) + profile_Voxel_Lost.erase(iter); + + profile_Voxel_AddOrChange[id] = profile; + } + + for(DefVoxelId id : data.Profile_Voxel_Lost) { + profile_Voxel_AddOrChange.erase(id); + } + + profile_Voxel_Lost.insert(profile_Voxel_Lost.end(), data.Profile_Voxel_Lost.begin(), data.Profile_Voxel_Lost.end()); + std::sort(profile_Voxel_Lost.begin(), profile_Voxel_Lost.end()); + auto eraseIter = std::unique(profile_Voxel_Lost.begin(), profile_Voxel_Lost.end()); + profile_Voxel_Lost.erase(eraseIter, profile_Voxel_Lost.end()); + } + + { + for(auto& [id, profile] : data.Profile_Node_AddOrChange) { + auto iter = std::lower_bound(profile_Node_Lost.begin(), profile_Node_Lost.end(), id); + if(iter != profile_Node_Lost.end()) + profile_Node_Lost.erase(iter); + + profile_Node_AddOrChange[id] = profile; + } + + for(DefNodeId id : data.Profile_Node_Lost) { + profile_Node_AddOrChange.erase(id); + } + + profile_Node_Lost.insert(profile_Node_Lost.end(), data.Profile_Node_Lost.begin(), data.Profile_Node_Lost.end()); + std::sort(profile_Node_Lost.begin(), profile_Node_Lost.end()); + auto eraseIter = std::unique(profile_Node_Lost.begin(), profile_Node_Lost.end()); + profile_Node_Lost.erase(eraseIter, profile_Node_Lost.end()); + } + + { + for(auto& [id, profile] : data.Profile_World_AddOrChange) { + auto iter = std::lower_bound(profile_World_Lost.begin(), profile_World_Lost.end(), id); + if(iter != profile_World_Lost.end()) + profile_World_Lost.erase(iter); + + profile_World_AddOrChange[id] = profile; + } + + for(DefWorldId id : data.Profile_World_Lost) { + profile_World_AddOrChange.erase(id); + } + + profile_World_Lost.insert(profile_World_Lost.end(), data.Profile_World_Lost.begin(), data.Profile_World_Lost.end()); + std::sort(profile_World_Lost.begin(), profile_World_Lost.end()); + auto eraseIter = std::unique(profile_World_Lost.begin(), profile_World_Lost.end()); + profile_World_Lost.erase(eraseIter, profile_World_Lost.end()); + } + + { + for(auto& [id, profile] : data.Profile_Portal_AddOrChange) { + auto iter = std::lower_bound(profile_Portal_Lost.begin(), profile_Portal_Lost.end(), id); + if(iter != profile_Portal_Lost.end()) + profile_Portal_Lost.erase(iter); + + profile_Portal_AddOrChange[id] = profile; + } + + for(DefPortalId id : data.Profile_Portal_Lost) { + profile_Portal_AddOrChange.erase(id); + } + + profile_Portal_Lost.insert(profile_Portal_Lost.end(), data.Profile_Portal_Lost.begin(), data.Profile_Portal_Lost.end()); + std::sort(profile_Portal_Lost.begin(), profile_Portal_Lost.end()); + auto eraseIter = std::unique(profile_Portal_Lost.begin(), profile_Portal_Lost.end()); + profile_Portal_Lost.erase(eraseIter, profile_Portal_Lost.end()); + } + + { + for(auto& [id, profile] : data.Profile_Entity_AddOrChange) { + auto iter = std::lower_bound(profile_Entity_Lost.begin(), profile_Entity_Lost.end(), id); + if(iter != profile_Entity_Lost.end()) + profile_Entity_Lost.erase(iter); + + profile_Entity_AddOrChange[id] = profile; + } + + for(DefEntityId id : data.Profile_Entity_Lost) { + profile_Entity_AddOrChange.erase(id); + } + + profile_Entity_Lost.insert(profile_Entity_Lost.end(), data.Profile_Entity_Lost.begin(), data.Profile_Entity_Lost.end()); + std::sort(profile_Entity_Lost.begin(), profile_Entity_Lost.end()); + auto eraseIter = std::unique(profile_Entity_Lost.begin(), profile_Entity_Lost.end()); + profile_Entity_Lost.erase(eraseIter, profile_Entity_Lost.end()); + } + + { + for(auto& [id, profile] : data.Profile_Item_AddOrChange) { + auto iter = std::lower_bound(profile_Item_Lost.begin(), profile_Item_Lost.end(), id); + if(iter != profile_Item_Lost.end()) + profile_Item_Lost.erase(iter); + + profile_Item_AddOrChange[id] = profile; + } + + for(DefItemId id : data.Profile_Item_Lost) { + profile_Item_AddOrChange.erase(id); + } + + profile_Item_Lost.insert(profile_Item_Lost.end(), data.Profile_Item_Lost.begin(), data.Profile_Item_Lost.end()); + std::sort(profile_Item_Lost.begin(), profile_Item_Lost.end()); + auto eraseIter = std::unique(profile_Item_Lost.begin(), profile_Item_Lost.end()); + profile_Item_Lost.erase(eraseIter, profile_Item_Lost.end()); + } + } + + for(auto& [id, _] : profile_Voxel_AddOrChange) + result.Profiles_ChangeOrAdd[EnumDefContent::Voxel].push_back(id); + result.Profiles_Lost[EnumDefContent::Voxel] = profile_Voxel_Lost; + + for(auto& [id, _] : profile_Node_AddOrChange) + result.Profiles_ChangeOrAdd[EnumDefContent::Node].push_back(id); + result.Profiles_Lost[EnumDefContent::Node] = profile_Node_Lost; + + for(auto& [id, _] : profile_World_AddOrChange) + result.Profiles_ChangeOrAdd[EnumDefContent::World].push_back(id); + result.Profiles_Lost[EnumDefContent::World] = profile_World_Lost; + + for(auto& [id, _] : profile_Portal_AddOrChange) + result.Profiles_ChangeOrAdd[EnumDefContent::Portal].push_back(id); + result.Profiles_Lost[EnumDefContent::Portal] = profile_Portal_Lost; + + for(auto& [id, _] : profile_Entity_AddOrChange) + result.Profiles_ChangeOrAdd[EnumDefContent::Entity].push_back(id); + result.Profiles_Lost[EnumDefContent::Entity] = profile_Entity_Lost; + + for(auto& [id, _] : profile_Item_AddOrChange) + result.Profiles_ChangeOrAdd[EnumDefContent::Item].push_back(id); + result.Profiles_Lost[EnumDefContent::Item] = profile_Item_Lost; + } + + // Чанки + std::unordered_map>> chunks_AddOrChange_Voxel_Result; + std::unordered_map>> chunks_AddOrChange_Node_Result; + std::unordered_map> chunks_Changed; + std::unordered_map> regions_Lost_Result; + + { + std::unordered_map> chunks_AddOrChange_Voxel; + std::unordered_map> chunks_AddOrChange_Node; + std::unordered_map> regions_Lost; + + for(TickData& data : ticks) { + for(auto& [wId, chunks] : data.Chunks_AddOrChange_Voxel) { + if(auto iter = regions_Lost.find(wId); iter != regions_Lost.end()) { + for(const auto& [pos, value] : chunks) { + iter->second.erase(Pos::GlobalRegion(pos >> 2)); + } + } + + chunks_AddOrChange_Voxel[wId].merge(chunks); + } + + data.Chunks_AddOrChange_Voxel.clear(); + + for(auto& [wId, chunks] : data.Chunks_AddOrChange_Node) { + if(auto iter = regions_Lost.find(wId); iter != regions_Lost.end()) { + for(const auto& [pos, value] : chunks) { + iter->second.erase(Pos::GlobalRegion(pos >> 2)); + } + } + + chunks_AddOrChange_Node[wId].merge(chunks); + } + + data.Chunks_AddOrChange_Node.clear(); + + for(auto& [wId, regions] : data.Regions_Lost) { + std::sort(regions.begin(), regions.end()); + + if(auto iter = chunks_AddOrChange_Voxel.find(wId); iter != chunks_AddOrChange_Voxel.end()) + { + std::vector toDelete; + for(auto& [pos, value] : iter->second) { + if(std::binary_search(regions.begin(), regions.end(), Pos::GlobalRegion(pos >> 2))) { + toDelete.push_back(pos); + } + } + + for(Pos::GlobalChunk pos : toDelete) + iter->second.erase(iter->second.find(pos)); + } + + if(auto iter = chunks_AddOrChange_Node.find(wId); iter != chunks_AddOrChange_Node.end()) + { + std::vector toDelete; + for(auto& [pos, value] : iter->second) { + if(std::binary_search(regions.begin(), regions.end(), Pos::GlobalRegion(pos >> 2))) { + toDelete.push_back(pos); + } + } + + for(Pos::GlobalChunk pos : toDelete) + iter->second.erase(iter->second.find(pos)); + } + + regions_Lost[wId].insert_range(regions); + } + + data.Regions_Lost.clear(); + } + + for(auto& [wId, list] : chunks_AddOrChange_Voxel) { + auto& caocvr = chunks_AddOrChange_Voxel_Result[wId]; + auto& c = chunks_Changed[wId]; + + for(auto& [pos, val] : list) { + caocvr[pos] = unCompressVoxels(val); + c.push_back(pos); + } + } + + for(auto& [wId, list] : chunks_AddOrChange_Node) { + auto& caocvr = chunks_AddOrChange_Node_Result[wId]; + auto& c = chunks_Changed[wId]; + + for(auto& [pos, val] : list) { + unCompressNodes(val, caocvr[pos].data()); + c.push_back(pos); + } + } + + regions_Lost_Result = std::move(regions_Lost); + + for(auto& [wId, list] : chunks_Changed) { + std::sort(list.begin(), list.end()); + auto eraseIter = std::unique(list.begin(), list.end()); + list.erase(eraseIter, list.end()); + } + } + + result.Chunks_ChangeOrAdd = std::move(chunks_Changed); + { + for(TickData& data : ticks) { + } + } if(RS) RS->pushStageTickSync(); @@ -484,58 +705,9 @@ void ServerSession::update(GlobalTime gTime, float dTime) { std::unordered_map> lostResources; // Обработка полученных ресурсов - - - // Обработка полученных тактов - while(!AsyncContext.TickSequence.get_read().empty()) { - TickData tick; - - { - auto lock = AsyncContext.TickSequence.lock(); - tick = lock->front(); - lock->pop(); - } - - // Потерянные привязки ресурсов - for(int type = 0; type < (int) EnumAssets::MAX_ENUM; type++) { - for(ResourceId id : tick.AssetsLost[type]) { - Assets.ExistBinds[type].erase(id); - changedResources[(EnumAssets) type].erase(id); - } - // Assets.ExistBinds[type].erase(tick.AssetsLost[type].begin(), tick.AssetsLost[type].end()); - lostResources[(EnumAssets) type].insert_range(tick.AssetsLost[type]); - } - - } // Получаем ресурсы, загруженные с дискового кеша - if(RS) { - // Уведомляем рендер опотерянных и изменённых ресурсах - if(!lostResources.empty()) { - std::unordered_map> lostResources2; - - for(auto& [type, list] : lostResources) - lostResources2[type].append_range(list); - - lostResources.clear(); - RS->onAssetsLost(std::move(lostResources2)); - } - - if(!changedResources.empty()) { - std::unordered_map> changedResources2; - - for(auto& [type, list] : changedResources) { - auto& a = changedResources2[type]; - for(auto& [key, val] : list) - a.push_back(val); - } - - changedResources.clear(); - RS->onAssetsChanges(std::move(changedResources2)); - } - } - GTime = gTime; Pos += glm::vec3(Speed) * dTime; @@ -556,105 +728,13 @@ void ServerSession::update(GlobalTime gTime, float dTime) { Speed += glm::vec3(0, -1, 0)*float(Keys.SHIFT)*mltpl; Speed += glm::vec3(0, 1, 0)*float(Keys.SPACE)*mltpl; - { - std::unordered_map, std::unordered_set>> changeOrAddList_removeList; - std::unordered_map> onContentDefinesAdd; - std::unordered_map> onContentDefinesLost; - - // Пакеты - ParsedPacket *pack; - while(NetInputPackets.pop(pack)) { - if(pack->Level1 == ToClient::L1::Definition) { - ToClient::L2Definition l2 = ToClient::L2Definition(pack->Level2); - - if(l2 == ToClient::L2Definition::Voxel) { - PP_Definition_Voxel &p = *dynamic_cast(pack); - Registry.DefVoxel[p.Id] = p.Def; - onContentDefinesAdd[EnumDefContent::Voxel].push_back(p.Id); - } else if(l2 == ToClient::L2Definition::FreeVoxel) { - PP_Definition_FreeVoxel &p = *dynamic_cast(pack); - { - auto iter = Registry.DefVoxel.find(p.Id); - if(iter != Registry.DefVoxel.end()) - Registry.DefVoxel.erase(iter); - } - onContentDefinesLost[EnumDefContent::Voxel].push_back(p.Id); - } else if(l2 == ToClient::L2Definition::Node) { - PP_Definition_Node &p = *dynamic_cast(pack); - Registry.DefNode[p.Id] = p.Def; - onContentDefinesAdd[EnumDefContent::Node].push_back(p.Id); - } else if(l2 == ToClient::L2Definition::FreeNode) { - PP_Definition_FreeNode &p = *dynamic_cast(pack); - { - auto iter = Registry.DefNode.find(p.Id); - if(iter != Registry.DefNode.end()) - Registry.DefNode.erase(iter); - } - onContentDefinesLost[EnumDefContent::Node].push_back(p.Id); - } - - } else if(pack->Level1 == ToClient::L1::Content) { - ToClient::L2Content l2 = ToClient::L2Content(pack->Level2); - if(l2 == ToClient::L2Content::ChunkVoxels) { - PP_Content_ChunkVoxels &p = *dynamic_cast(pack); - Pos::GlobalRegion rPos = p.Pos >> 2; - Pos::bvec4u cPos = p.Pos & 0x3; - - Data.Worlds[p.Id].Regions[rPos].Chunks[cPos.pack()].Voxels = std::move(p.Cubes); - - auto &pair = changeOrAddList_removeList[p.Id]; - std::get<0>(pair).insert(p.Pos); - } else if(l2 == ToClient::L2Content::ChunkNodes) { - PP_Content_ChunkNodes &p = *dynamic_cast(pack); - Pos::GlobalRegion rPos = p.Pos >> 2; - Pos::bvec4u cPos = p.Pos & 0x3; - - Node *nodes = (Node*) Data.Worlds[p.Id].Regions[rPos].Chunks[cPos.pack()].Nodes.data(); - std::copy(p.Nodes.begin(), p.Nodes.end(), nodes); - - auto &pair = changeOrAddList_removeList[p.Id]; - std::get<0>(pair).insert(p.Pos); - } else if(l2 == ToClient::L2Content::RemoveRegion) { - PP_Content_RegionRemove &p = *dynamic_cast(pack); - - auto ®ions = Data.Worlds[p.Id].Regions; - auto obj = regions.find(p.Pos); - if(obj != regions.end()) { - regions.erase(obj); - - auto &pair = changeOrAddList_removeList[p.Id]; - std::get<1>(pair).insert(p.Pos); - } - } - } - - delete pack; - } - - if(RS && !changeOrAddList_removeList.empty()) { - for(auto &pair : changeOrAddList_removeList) { - // Если случится что чанк был изменён и удалён, то исключаем его обновления - for(Pos::GlobalRegion removed : std::get<1>(pair.second)) { - Pos::GlobalChunk pos = Pos::GlobalChunk(removed) << 2; - for(int z = 0; z < 4; z++) - for(int y = 0; y < 4; y++) - for(int x = 0; x < 4; x++) { - std::get<0>(pair.second).erase(pos+Pos::GlobalChunk(x, y, z)); - } - } - - RS->onChunksChange(pair.first, std::get<0>(pair.second), std::get<1>(pair.second)); - } - - if(!onContentDefinesAdd.empty()) { - RS->onContentDefinesAdd(std::move(onContentDefinesAdd)); - } - - if(!onContentDefinesLost.empty()) { - RS->onContentDefinesLost(std::move(onContentDefinesLost)); - } - } - } + // { + // // Пакеты + // ParsedPacket *pack; + // while(NetInputPackets.pop(pack)) { + // delete pack; + // } + // } // Расчёт камеры { @@ -756,7 +836,7 @@ coro<> ServerSession::rP_System(Net::AsyncSocket &sock) { co_return; case ToClient::L2System::SyncTick: - AsyncContext.TickSequence.lock()->push(std::move(AsyncContext.ThisTickEntry)); + AsyncContext.TickSequence.lock()->push_back(std::move(AsyncContext.ThisTickEntry)); co_return; default: protocolError(); @@ -770,7 +850,8 @@ coro<> ServerSession::rP_Resource(Net::AsyncSocket &sock) { case ToClient::L2Resource::Bind: { uint32_t count = co_await sock.read(); - AsyncContext.ThisTickEntry.AssetsBinds.reserve(AsyncContext.ThisTickEntry.AssetsBinds.size()+count); + std::vector binds; + binds.reserve(count); for(size_t iter = 0; iter < count; iter++) { uint8_t type = co_await sock.read(); @@ -781,22 +862,27 @@ coro<> ServerSession::rP_Resource(Net::AsyncSocket &sock) { Hash_t hash; co_await sock.read((std::byte*) hash.data(), hash.size()); - AsyncContext.ThisTickEntry.AssetsBinds.emplace_back( + binds.emplace_back( (EnumAssets) type, (ResourceId) id, std::move(domain), std::move(key), hash ); } + + AsyncContext.AssetsBinds.lock()->push_back(AssetsBindsChange(binds, {})); } case ToClient::L2Resource::Lost: { uint32_t count = co_await sock.read(); + AssetsBindsChange abc; for(size_t iter = 0; iter < count; iter++) { uint8_t type = co_await sock.read(); uint32_t id = co_await sock.read(); - AsyncContext.ThisTickEntry.AssetsLost[(int) type].push_back(id); + abc.Lost[(int) type].push_back(id); } + + AsyncContext.AssetsBinds.lock()->emplace_back(std::move(abc)); } case ToClient::L2Resource::InitResSend: { @@ -892,11 +978,6 @@ coro<> ServerSession::rP_Definition(Net::AsyncSocket &sock) { { DefNodeId id = co_await sock.read(); - PP_Definition_FreeNode *packet = new PP_Definition_FreeNode( - id - ); - - while(!NetInputPackets.push(packet)); co_return; } @@ -921,12 +1002,16 @@ coro<> ServerSession::rP_Content(Net::AsyncSocket &sock) { uint8_t second = co_await sock.read(); switch((ToClient::L2Content) second) { - case ToClient::L2Content::World: - + case ToClient::L2Content::World: { + WorldId_t wId = co_await sock.read(); + AsyncContext.ThisTickEntry.Worlds_AddOrChange.emplace_back(wId, nullptr); co_return; - case ToClient::L2Content::RemoveWorld: - + } + case ToClient::L2Content::RemoveWorld: { + WorldId_t wId = co_await sock.read(); + AsyncContext.ThisTickEntry.Worlds_Lost.push_back(wId); co_return; + } case ToClient::L2Content::Portal: co_return; @@ -950,13 +1035,7 @@ coro<> ServerSession::rP_Content(Net::AsyncSocket &sock) { std::u8string compressed(compressedSize, '\0'); co_await sock.read((std::byte*) compressed.data(), compressedSize); - PP_Content_ChunkVoxels *packet = new PP_Content_ChunkVoxels( - wcId, - pos, - unCompressVoxels(compressed) // TODO: вынести в отдельный поток - ); - - while(!NetInputPackets.push(packet)); + AsyncContext.ThisTickEntry.Chunks_AddOrChange_Node[wcId].insert({pos, std::move(compressed)}); co_return; } @@ -972,14 +1051,7 @@ coro<> ServerSession::rP_Content(Net::AsyncSocket &sock) { std::u8string compressed(compressedSize, '\0'); co_await sock.read((std::byte*) compressed.data(), compressedSize); - PP_Content_ChunkNodes *packet = new PP_Content_ChunkNodes( - wcId, - pos - ); - - unCompressNodes(compressed, (Node*) packet->Nodes.data()); // TODO: вынести в отдельный поток - - while(!NetInputPackets.push(packet)); + AsyncContext.ThisTickEntry.Chunks_AddOrChange_Node[wcId].insert({pos, std::move(compressed)}); co_return; } @@ -991,12 +1063,7 @@ coro<> ServerSession::rP_Content(Net::AsyncSocket &sock) { Pos::GlobalRegion pos; pos.unpack(co_await sock.read()); - PP_Content_RegionRemove *packet = new PP_Content_RegionRemove( - wcId, - pos - ); - - while(!NetInputPackets.push(packet)); + AsyncContext.ThisTickEntry.Regions_Lost[wcId].push_back(pos); co_return; } diff --git a/Src/Client/ServerSession.hpp b/Src/Client/ServerSession.hpp index 4d3a9fa..390ac24 100644 --- a/Src/Client/ServerSession.hpp +++ b/Src/Client/ServerSession.hpp @@ -19,16 +19,6 @@ namespace LV::Client { -struct ParsedPacket { - ToClient::L1 Level1; - uint8_t Level2; - - ParsedPacket(ToClient::L1 l1, uint8_t l2) - : Level1(l1), Level2(l2) - {} - virtual ~ParsedPacket(); -}; - class ServerSession : public IAsyncDestructible, public IServerSession, public ISurfaceEventListener { public: using Ptr = std::shared_ptr; @@ -102,9 +92,25 @@ private: }; struct TickData { - std::vector LostWorld; - // std::vector> + std::vector> Profile_Voxel_AddOrChange; + std::vector Profile_Voxel_Lost; + std::vector> Profile_Node_AddOrChange; + std::vector Profile_Node_Lost; + std::vector> Profile_World_AddOrChange; + std::vector Profile_World_Lost; + std::vector> Profile_Portal_AddOrChange; + std::vector Profile_Portal_Lost; + std::vector> Profile_Entity_AddOrChange; + std::vector Profile_Entity_Lost; + std::vector> Profile_Item_AddOrChange; + std::vector Profile_Item_Lost; + std::vector> Worlds_AddOrChange; + std::vector Worlds_Lost; + + std::unordered_map> Chunks_AddOrChange_Voxel; + std::unordered_map> Chunks_AddOrChange_Node; + std::unordered_map> Regions_Lost; }; struct AssetsBindsChange { @@ -121,13 +127,15 @@ private: // Накопление данных за такт сервера TickData ThisTickEntry; - // Сбда обращается ветка обновления IServerSession, накапливая данные до SyncTick + // Сюда обращается ветка обновления IServerSession, накапливая данные до SyncTick // Ресурсы, ожидающие ответа от менеджера кеша std::unordered_map>> ResourceWait[(int) EnumAssets::MAX_ENUM]; // Полученные ресурсы в ожидании стадии синхронизации такта std::unordered_map> ReceivedResources; // Полученные изменения связок в ожидании стадии синхронизации такта - AssetsBindsChange Binds; + std::vector Binds; + // Подгруженные меж тактами ресурсы + std::vector> LoadedResources; // Список ресурсов на которые уже был отправлен запрос на загрузку ресурса std::vector AlreadyLoading; @@ -138,15 +146,13 @@ private: // Изменения в наблюдаемых ресурсах TOS::SpinlockObject> AssetsBinds; // Пакеты обновлений игрового мира - TOS::SpinlockObject> TickSequence; + TOS::SpinlockObject> TickSequence; } AsyncContext; bool IsConnected = true, IsGoingShutdown = false; - boost::lockfree::spsc_queue NetInputPackets; - // PYR - поворот камеры по осям xyz в радианах, PYR_Offset для сглаживание поворота glm::vec3 PYR = glm::vec3(0), PYR_Offset = glm::vec3(0); double PYR_At = 0; diff --git a/Src/Server/RemoteClient.cpp b/Src/Server/RemoteClient.cpp index a610828..4fe4836 100644 --- a/Src/Server/RemoteClient.cpp +++ b/Src/Server/RemoteClient.cpp @@ -734,7 +734,7 @@ coro<> RemoteClient::rP_System(Net::AsyncSocket &sock) { } case ToServer::L2System::ResourceRequest: { - uint16_t count = co_await sock.read(); + uint16_t count = co_await sock.read(); std::vector hashes; hashes.reserve(count);