From 6dd1f93221a9da43c27ad05c178d00a2e4058f47 Mon Sep 17 00:00:00 2001 From: DrSocalkwe3n Date: Sun, 4 Jan 2026 20:47:48 +0600 Subject: [PATCH] =?UTF-8?q?=D0=9E=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B8=D1=84=D0=B8=D0=BA?= =?UTF-8?q?=D0=B0=D1=82=D0=BE=D1=80=D0=BE=D0=B2=20=D0=BF=D1=80=D0=B8=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Src/Client/ServerSession.cpp | 64 ---------------------------------- Src/Common/AssetsPreloader.cpp | 25 +++++++++++++ Src/Common/AssetsPreloader.hpp | 17 +++++++++ Src/Server/GameServer.cpp | 26 ++++++++++++-- 4 files changed, 65 insertions(+), 67 deletions(-) diff --git a/Src/Client/ServerSession.cpp b/Src/Client/ServerSession.cpp index dd1690a..70d2ece 100644 --- a/Src/Client/ServerSession.cpp +++ b/Src/Client/ServerSession.cpp @@ -38,69 +38,6 @@ const char* assetTypeName(EnumAssets type) { } } -std::optional debugExpectedGeneratedNodeId(int rx, int ry, int rz) { - if(ry == 1 && rz == 0) - return DefNodeId(0); - if(rx == 0 && ry == 1) - return DefNodeId(0); - if(rx == 0 && rz == 0) - return DefNodeId(1); - if(ry == 0 && rz == 0) - return DefNodeId(2); - if(rx == 0 && ry == 0) - return DefNodeId(3); - return std::nullopt; -} - -void debugCheckGeneratedChunkNodes(WorldId_t worldId, - Pos::GlobalChunk chunkPos, - const std::array& chunk) -{ - if(chunkPos[0] != 0 && chunkPos[1] != 0 && chunkPos[2] != 0) - return; - - static std::atomic warnCount = 0; - if(warnCount.load() >= 16) - return; - - Pos::bvec4u localChunk = chunkPos & 0x3; - const int baseX = int(localChunk[0]) * 16; - const int baseY = int(localChunk[1]) * 16; - const int baseZ = int(localChunk[2]) * 16; - const int globalBaseX = int(chunkPos[0]) * 16; - const int globalBaseY = int(chunkPos[1]) * 16; - const int globalBaseZ = int(chunkPos[2]) * 16; - - for(int z = 0; z < 16; z++) - for(int y = 0; y < 16; y++) - for(int x = 0; x < 16; x++) { - int rx = baseX + x; - int ry = baseY + y; - int rz = baseZ + z; - int gx = globalBaseX + x; - int gy = globalBaseY + y; - int gz = globalBaseZ + z; - std::optional expected = debugExpectedGeneratedNodeId(rx, ry, rz); - if(!expected) - continue; - - const Node& node = chunk[x + y * 16 + z * 16 * 16]; - if(node.NodeId != *expected) { - uint32_t index = warnCount.fetch_add(1); - if(index < 16) { - TOS::Logger("Client>WorldDebug").warn() - << "Generated node mismatch world " << worldId - << " chunk " << int(chunkPos[0]) << ',' << int(chunkPos[1]) << ',' << int(chunkPos[2]) - << " at local " << rx << ',' << ry << ',' << rz - << " global " << gx << ',' << gy << ',' << gz - << " expected " << *expected - << " got " << node.NodeId; - } - return; - } - } -} - } ServerSession::ServerSession(asio::io_context &ioc, std::unique_ptr&& socket) @@ -919,7 +856,6 @@ void ServerSession::update(GlobalTime gTime, float dTime) { auto& chunkNodes = caocvr[pos]; unCompressNodes(val, chunkNodes.data()); - debugCheckGeneratedChunkNodes(wId, pos, chunkNodes); c.push_back(pos); } } diff --git a/Src/Common/AssetsPreloader.cpp b/Src/Common/AssetsPreloader.cpp index 59dccda..ed056b4 100644 --- a/Src/Common/AssetsPreloader.cpp +++ b/Src/Common/AssetsPreloader.cpp @@ -421,6 +421,31 @@ AssetsPreloader::Out_bakeId AssetsPreloader::bakeIdTables() { return result; } +AssetsPreloader::Out_fullSync AssetsPreloader::collectFullSync() const { + Out_fullSync out; + + for(size_t type = 0; type < static_cast(AssetType::MAX_ENUM); ++type) { + out.IdToDK[type] = IdToDK[type]; + } + + for(size_t type = 0; type < static_cast(AssetType::MAX_ENUM); ++type) { + for(const auto& [id, resource] : MediaResources[type]) { + out.HashHeaders[type].push_back(BindHashHeaderInfo{ + .Id = id, + .Hash = resource.Hash, + .Header = resource.Header + }); + out.Resources.emplace_back( + static_cast(type), + id, + &resource + ); + } + } + + return out; +} + std::tuple, std::vector> AssetsPreloader::getNodeDependency(const std::string& domain, const std::string& key) { (void)domain; diff --git a/Src/Common/AssetsPreloader.hpp b/Src/Common/AssetsPreloader.hpp index c9715b0..319514b 100644 --- a/Src/Common/AssetsPreloader.hpp +++ b/Src/Common/AssetsPreloader.hpp @@ -143,6 +143,20 @@ public: > IdToDK; }; + struct Out_fullSync { + std::array< + std::vector, + static_cast(AssetType::MAX_ENUM) + > IdToDK; + + std::array< + std::vector, + static_cast(AssetType::MAX_ENUM) + > HashHeaders; + + std::vector> Resources; + }; + struct ReloadStatus { /// TODO: callback'и для обновления статусов /// TODO: многоуровневый статус std::vector. Этапы/Шаги/Объекты @@ -218,6 +232,9 @@ public: */ Out_bakeId bakeIdTables(); + // Выдаёт полный список привязок и ресурсов для новых клиентов. + Out_fullSync collectFullSync() const; + /* Выдаёт пакет со всеми текущими привязками id -> домен+ключ. Используется при подключении новых клиентов. diff --git a/Src/Server/GameServer.cpp b/Src/Server/GameServer.cpp index e682ae0..9ddfc8a 100644 --- a/Src/Server/GameServer.cpp +++ b/Src/Server/GameServer.cpp @@ -1582,6 +1582,7 @@ void GameServer::requestModsReload() { } void GameServer::stepConnections() { + std::vector> newClients; // Подключить новых игроков if(!External.NewConnectedPlayers.no_lock_readable().empty()) { auto lock = External.NewConnectedPlayers.lock_write(); @@ -1589,11 +1590,27 @@ void GameServer::stepConnections() { for(std::shared_ptr& client : *lock) { co_spawn(client->run()); Game.RemoteClients.push_back(client); + newClients.push_back(client); } lock->clear(); } + if(!newClients.empty()) { + AssetsPreloader::Out_fullSync fullSync = Content.AM.collectFullSync(); + std::array, static_cast(EnumAssets::MAX_ENUM)> lost{}; + + std::vector packets = RemoteClient::makePackets_informateAssets_DK(fullSync.IdToDK); + packets.push_back(RemoteClient::makePacket_informateAssets_HH(fullSync.HashHeaders, lost)); + + for(const std::shared_ptr& client : newClients) { + if(!packets.empty()) { + auto copy = packets; + client->pushPackets(©); + } + } + } + BackingChunkPressure.endCollectChanges(); // Отключение игроков @@ -1676,8 +1693,10 @@ void GameServer::reloadMods() { { AssetsPreloader::Out_bakeId baked = Content.AM.bakeIdTables(); - if(!baked.IdToDK.empty()) - packetsToSend.push_back(RemoteClient::makePacket_informateAssets_DK(baked.IdToDK)); + if(!baked.IdToDK.empty()) { + std::vector dkPackets = RemoteClient::makePackets_informateAssets_DK(baked.IdToDK); + packetsToSend.insert(packetsToSend.end(), dkPackets.begin(), dkPackets.end()); + } } } @@ -2469,7 +2488,8 @@ void GameServer::stepSyncContent() { { AssetsPreloader::Out_bakeId baked = Content.AM.bakeIdTables(); if(!baked.IdToDK.empty()) { - packetsToAll.push_back(RemoteClient::makePacket_informateAssets_DK(baked.IdToDK)); + std::vector dkPackets = RemoteClient::makePackets_informateAssets_DK(baked.IdToDK); + packetsToAll.insert(packetsToAll.end(), dkPackets.begin(), dkPackets.end()); } }