From 4eef3ca21147c7106a51b70022ee5ddd4fcfdd4a Mon Sep 17 00:00:00 2001 From: DrSocalkwe3n Date: Tue, 2 Sep 2025 13:03:39 +0600 Subject: [PATCH] =?UTF-8?q?=D0=9E=D1=82=D0=BB=D0=B0=D0=B4=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=80?= =?UTF-8?q?=D0=B5=D1=81=D1=83=D1=80=D1=81=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Src/Client/AssetsManager.cpp | 12 ++-- Src/Client/ServerSession.cpp | 77 +++++++++++++---------- Src/Client/ServerSession.hpp | 4 +- Src/Client/Vulkan/VulkanRenderSession.hpp | 2 +- Src/Common/Abstract.cpp | 6 +- Src/Server/AssetsManager.cpp | 36 +++++++++++ Src/Server/AssetsManager.hpp | 28 +++++++++ Src/Server/GameServer.cpp | 35 ++++++----- Src/Server/GameServer.hpp | 2 +- Src/Server/RemoteClient.cpp | 12 ++-- 10 files changed, 149 insertions(+), 65 deletions(-) diff --git a/Src/Client/AssetsManager.cpp b/Src/Client/AssetsManager.cpp index 4da54bb..fecf85a 100644 --- a/Src/Client/AssetsManager.cpp +++ b/Src/Client/AssetsManager.cpp @@ -249,7 +249,7 @@ void AssetsManager::readWriteThread(AsyncUseControl::Lock lock) { // Нашли finded = true; Resource res = Resource(end).convertToMem(); - ReadyQueue.lock()->emplace_back(rk.Hash, res); + ReadyQueue.lock()->emplace_back(rk, res); break; } } @@ -264,7 +264,7 @@ void AssetsManager::readWriteThread(AsyncUseControl::Lock lock) { int size = sqlite3_column_bytes(STMT_INLINE_GET, 0); Resource res(hash, size); finded = true; - ReadyQueue.lock()->emplace_back(rk.Hash, res); + ReadyQueue.lock()->emplace_back(rk, res); } else if(errc != SQLITE_DONE) { sqlite3_reset(STMT_INLINE_GET); MAKE_ERROR("Не удалось выполнить подготовленный запрос STMT_INLINE_GET: " << sqlite3_errmsg(DB)); @@ -323,7 +323,7 @@ void AssetsManager::readWriteThread(AsyncUseControl::Lock lock) { if(!finded) { // Не нашли - ReadyQueue.lock()->emplace_back(rk.Hash, std::nullopt); + ReadyQueue.lock()->emplace_back(rk, std::nullopt); } continue; @@ -342,7 +342,8 @@ void AssetsManager::readWriteThread(AsyncUseControl::Lock lock) { // TODO: добавить вычистку места при нехватке if(res.size() <= SMALL_RESOURCE) { - sqlite3_bind_blob(STMT_INLINE_INSERT, 1, (const void*) res.hash().data(), 32, SQLITE_STATIC); + Hash_t hash = res.hash(); + sqlite3_bind_blob(STMT_INLINE_INSERT, 1, (const void*) hash.data(), 32, SQLITE_STATIC); sqlite3_bind_int(STMT_INLINE_INSERT, 2, time(nullptr)); sqlite3_bind_blob(STMT_INLINE_INSERT, 3, res.data(), res.size(), SQLITE_STATIC); if(sqlite3_step(STMT_INLINE_INSERT) != SQLITE_DONE) { @@ -371,7 +372,8 @@ void AssetsManager::readWriteThread(AsyncUseControl::Lock lock) { fd.close(); - sqlite3_bind_blob(STMT_DISK_INSERT, 1, (const void*) res.hash().data(), 32, SQLITE_STATIC); + Hash_t hash = res.hash(); + sqlite3_bind_blob(STMT_DISK_INSERT, 1, (const void*) hash.data(), 32, SQLITE_STATIC); sqlite3_bind_int(STMT_DISK_INSERT, 2, time(nullptr)); sqlite3_bind_int(STMT_DISK_INSERT, 3, res.size()); if(sqlite3_step(STMT_DISK_INSERT) != SQLITE_DONE) { diff --git a/Src/Client/ServerSession.cpp b/Src/Client/ServerSession.cpp index cfdcd9f..bd0df78 100644 --- a/Src/Client/ServerSession.cpp +++ b/Src/Client/ServerSession.cpp @@ -268,10 +268,10 @@ void ServerSession::update(GlobalTime gTime, float dTime) { AsyncContext.LoadedResources.emplace_back(std::move(entry)); // // Проверяем используется ли сейчас ресурс - // auto iter = Assets.ExistBinds[(int) entry.Type].find(entry.Id); - // if(iter == Assets.ExistBinds[(int) entry.Type].end()) { + // auto iter = MyAssets.ExistBinds[(int) entry.Type].find(entry.Id); + // if(iter == MyAssets.ExistBinds[(int) entry.Type].end()) { // // Не используется - // Assets.NotInUse[(int) entry.Type][entry.Domain + ':' + entry.Key] = {entry, TIME_BEFORE_UNLOAD_RESOURCE+time(nullptr)}; + // MyAssets.NotInUse[(int) entry.Type][entry.Domain + ':' + entry.Key] = {entry, TIME_BEFORE_UNLOAD_RESOURCE+time(nullptr)}; // } else { // // Используется // Assets.InUse[(int) entry.Type][entry.Id] = entry; @@ -290,10 +290,10 @@ void ServerSession::update(GlobalTime gTime, float dTime) { 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()); + auto iter = std::lower_bound(AsyncContext.AlreadyLoading.begin(), AsyncContext.AlreadyLoading.end(), key.Hash); + if(iter == AsyncContext.AlreadyLoading.end() || *iter != key.Hash) { + AsyncContext.AlreadyLoading.insert(iter, key.Hash); + needRequest.push_back(key.Hash); } } else { AssetEntry entry { @@ -339,7 +339,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) { const AssetBindEntry& abe = abc.Binds[iter]; auto& lost = entry.Lost[(int) abe.Type]; auto iterator = std::lower_bound(lost.begin(), lost.end(), abe.Id); - if(iterator != lost.end()) { + if(iterator != lost.end() && *iterator == abe.Id) { // Привязка будет удалена lost.erase(iterator); abc.Binds.erase(abc.Binds.begin()+iter); @@ -354,7 +354,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) { for(AssetBindEntry& abe : entry.Binds) { auto iterator = std::lower_bound(entry.Lost[(int) abe.Type].begin(), entry.Lost[(int) abe.Type].end(), abe.Id); - if(iterator != entry.Lost[(int) abe.Type].end()) { + if(iterator != entry.Lost[(int) abe.Type].end() && *iterator == abe.Id) { // Получили новую привязку, которая была удалена в предыдущем такте entry.Lost[(int) abe.Type].erase(iterator); } else { @@ -382,26 +382,26 @@ void ServerSession::update(GlobalTime gTime, float dTime) { // Запрос к дисковому кешу новых ресурсов std::vector needToLoad; for(const AssetBindEntry& bind : abc.Binds) { - bool needQuery = false; + bool needQuery = true; // Проверить in memory кеш по домену+ключу { std::string dk = bind.Domain + ':' + bind.Key; - auto &niubdk = Assets.NotInUse[(int) bind.Type]; + auto &niubdk = MyAssets.NotInUse[(int) bind.Type]; auto iter = niubdk.find(dk); if(iter != niubdk.end()) { // Есть ресурс - needQuery = true; + needQuery = false; } } // Проверить если такой запрос уже был отправлен в AssetsManager и ожидает ответа - if(!needQuery) { + if(needQuery) { auto& list = AsyncContext.ResourceWait[(int) bind.Type]; auto iterDomain = list.find(bind.Domain); if(iterDomain != list.end()) { for(const auto& [key, hash] : iterDomain->second) { if(key == bind.Key && hash == bind.Hash) { - needQuery = true; + needQuery = false; break; } } @@ -452,7 +452,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) { { 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()) + if(iter != profile_Voxel_Lost.end() && *iter == id) profile_Voxel_Lost.erase(iter); profile_Voxel_AddOrChange[id] = profile; @@ -471,7 +471,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) { { 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()) + if(iter != profile_Node_Lost.end() && *iter == id) profile_Node_Lost.erase(iter); profile_Node_AddOrChange[id] = profile; @@ -490,7 +490,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) { { 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()) + if(iter != profile_World_Lost.end() && *iter == id) profile_World_Lost.erase(iter); profile_World_AddOrChange[id] = profile; @@ -509,7 +509,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) { { 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()) + if(iter != profile_Portal_Lost.end() && *iter == id) profile_Portal_Lost.erase(iter); profile_Portal_AddOrChange[id] = profile; @@ -528,7 +528,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) { { 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()) + if(iter != profile_Entity_Lost.end() && *iter == id) profile_Entity_Lost.erase(iter); profile_Entity_AddOrChange[id] = profile; @@ -547,7 +547,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) { { 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()) + if(iter != profile_Item_Lost.end() && *iter == id) profile_Item_Lost.erase(iter); profile_Item_AddOrChange[id] = profile; @@ -713,7 +713,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) { const AssetBindEntry& abe = abc.Binds[iter]; auto& lost = entry.Lost[(int) abe.Type]; auto iterator = std::lower_bound(lost.begin(), lost.end(), abe.Id); - if(iterator != lost.end()) { + if(iterator != lost.end() && *iterator == abe.Id) { lost.erase(iterator); abc.Binds.erase(abc.Binds.begin()+iter); } @@ -727,7 +727,7 @@ void ServerSession::update(GlobalTime gTime, float dTime) { for(AssetBindEntry& abe : entry.Binds) { auto iterator = std::lower_bound(entry.Lost[(int) abe.Type].begin(), entry.Lost[(int) abe.Type].end(), abe.Id); - if(iterator != entry.Lost[(int) abe.Type].end()) { + if(iterator != entry.Lost[(int) abe.Type].end() && *iterator == abe.Id) { // Получили новую привязку, которая была удалена в предыдущем такте entry.Lost[(int) abe.Type].erase(iterator); } else { @@ -754,25 +754,25 @@ void ServerSession::update(GlobalTime gTime, float dTime) { AsyncContext.Binds.clear(); for(AssetBindEntry& entry : abc.Binds) { - Assets.ExistBinds[(int) entry.Type].insert(entry.Id); + MyAssets.ExistBinds[(int) entry.Type].insert(entry.Id); result.Assets_ChangeOrAdd[entry.Type].push_back(entry.Id); // Если ресурс был в кеше, то достаётся от туда - auto iter = Assets.NotInUse[(int) entry.Type].find(entry.Domain+':'+entry.Key); - if(iter != Assets.NotInUse[(int) entry.Type].end()) { + auto iter = MyAssets.NotInUse[(int) entry.Type].find(entry.Domain+':'+entry.Key); + if(iter != MyAssets.NotInUse[(int) entry.Type].end()) { IServerSession::Assets[entry.Type][entry.Id] = std::get<0>(iter->second); - Assets.NotInUse[(int) entry.Type].erase(iter); + MyAssets.NotInUse[(int) entry.Type].erase(iter); } } for(int type = 0; type < (int) EnumAssets::MAX_ENUM; type++) { for(ResourceId id : abc.Lost[type]) { - Assets.ExistBinds[type].erase(id); + MyAssets.ExistBinds[type].erase(id); // Потерянные ресурсы уходят в кеш auto iter = IServerSession::Assets[(EnumAssets) type].find(id); if(iter != IServerSession::Assets[(EnumAssets) type].end()) { - Assets.NotInUse[(int) iter->second.Type][iter->second.Domain+':'+iter->second.Key] = {iter->second, TIME_BEFORE_UNLOAD_RESOURCE+time(nullptr)}; + MyAssets.NotInUse[(int) iter->second.Type][iter->second.Domain+':'+iter->second.Key] = {iter->second, TIME_BEFORE_UNLOAD_RESOURCE+time(nullptr)}; IServerSession::Assets[(EnumAssets) type].erase(iter); } } @@ -784,12 +784,12 @@ void ServerSession::update(GlobalTime gTime, float dTime) { // Получаем ресурсы { for(AssetEntry& entry : AsyncContext.LoadedResources) { - if(Assets.ExistBinds[(int) entry.Type].contains(entry.Id)) { + if(MyAssets.ExistBinds[(int) entry.Type].contains(entry.Id)) { // Ресурс ещё нужен IServerSession::Assets[entry.Type][entry.Id] = entry; } else { // Ресурс уже не нужен, отправляем в кеш - Assets.NotInUse[(int) entry.Type][entry.Domain+':'+entry.Key] = {entry, TIME_BEFORE_UNLOAD_RESOURCE+time(nullptr)}; + MyAssets.NotInUse[(int) entry.Type][entry.Domain+':'+entry.Key] = {entry, TIME_BEFORE_UNLOAD_RESOURCE+time(nullptr)}; } } @@ -801,13 +801,13 @@ void ServerSession::update(GlobalTime gTime, float dTime) { uint64_t now = time(nullptr); for(int type = 0; type < (int) EnumAssets::MAX_ENUM; type++) { std::vector toDelete; - for(auto& [key, value] : Assets.NotInUse[type]) { + for(auto& [key, value] : MyAssets.NotInUse[type]) { if(std::get<1>(value) < now) toDelete.push_back(key); } for(std::string& key : toDelete) - Assets.NotInUse[type].erase(Assets.NotInUse[type].find(key)); + MyAssets.NotInUse[type].erase(MyAssets.NotInUse[type].find(key)); } } @@ -1017,6 +1017,10 @@ coro<> ServerSession::rP_Resource(Net::AsyncSocket &sock) { for(size_t iter = 0; iter < count; iter++) { uint8_t type = co_await sock.read(); + + if(type >= (int) EnumAssets::MAX_ENUM) + protocolError(); + uint32_t id = co_await sock.read(); std::string domain, key; domain = co_await sock.read(); @@ -1031,6 +1035,7 @@ coro<> ServerSession::rP_Resource(Net::AsyncSocket &sock) { } AsyncContext.AssetsBinds.lock()->push_back(AssetsBindsChange(binds, {})); + co_return; } case ToClient::L2Resource::Lost: { @@ -1041,10 +1046,14 @@ coro<> ServerSession::rP_Resource(Net::AsyncSocket &sock) { uint8_t type = co_await sock.read(); uint32_t id = co_await sock.read(); + if(type >= (int) EnumAssets::MAX_ENUM) + protocolError(); + abc.Lost[(int) type].push_back(id); } AsyncContext.AssetsBinds.lock()->emplace_back(std::move(abc)); + co_return; } case ToClient::L2Resource::InitResSend: { @@ -1053,6 +1062,10 @@ coro<> ServerSession::rP_Resource(Net::AsyncSocket &sock) { co_await sock.read((std::byte*) hash.data(), hash.size()); ResourceId id = co_await sock.read(); EnumAssets type = (EnumAssets) co_await sock.read(); + + if(type >= EnumAssets::MAX_ENUM) + protocolError(); + std::string domain = co_await sock.read(); std::string key = co_await sock.read(); diff --git a/Src/Client/ServerSession.hpp b/Src/Client/ServerSession.hpp index 5654282..4b59385 100644 --- a/Src/Client/ServerSession.hpp +++ b/Src/Client/ServerSession.hpp @@ -70,11 +70,9 @@ private: struct { // Существующие привязки ресурсов std::unordered_set ExistBinds[(int) EnumAssets::MAX_ENUM]; - // Используемые в данных момент ресурсы (определяется по действующей привязке) - std::unordered_map InUse[(int) EnumAssets::MAX_ENUM]; // Недавно использованные ресурсы, пока хранятся здесь в течении TIME_BEFORE_UNLOAD_RESOURCE секунд std::unordered_map> NotInUse[(int) EnumAssets::MAX_ENUM]; - } Assets; + } MyAssets; struct AssetLoading { EnumAssets Type; diff --git a/Src/Client/Vulkan/VulkanRenderSession.hpp b/Src/Client/Vulkan/VulkanRenderSession.hpp index 2d3fa25..c06021f 100644 --- a/Src/Client/Vulkan/VulkanRenderSession.hpp +++ b/Src/Client/Vulkan/VulkanRenderSession.hpp @@ -169,7 +169,7 @@ public: assert(vkInst); assert(serverSession); - CMG.changeThreadsCount(2); + CMG.changeThreadsCount(1); const VkCommandPoolCreateInfo infoCmdPool = { diff --git a/Src/Common/Abstract.cpp b/Src/Common/Abstract.cpp index cc93823..bcde7bb 100644 --- a/Src/Common/Abstract.cpp +++ b/Src/Common/Abstract.cpp @@ -2024,9 +2024,9 @@ Resource::Resource(const std::u8string& data) : In(std::make_shared>(InlinePtr((const uint8_t*) data.data(), data.size()))) {} -Resource::Resource(std::u8string&& data) { - -} +Resource::Resource(std::u8string&& data) + : In(std::make_shared>(InlinePtr(std::move(data)))) +{} const std::byte* Resource::data() const { assert(In); return std::visit([](auto& obj){ return obj.data(); }, *In); } size_t Resource::size() const { assert(In); return std::visit([](auto& obj){ return obj.size(); }, *In); } diff --git a/Src/Server/AssetsManager.cpp b/Src/Server/AssetsManager.cpp index da03036..b0c98f5 100644 --- a/Src/Server/AssetsManager.cpp +++ b/Src/Server/AssetsManager.cpp @@ -498,6 +498,8 @@ AssetsManager::Out_applyResourceChange AssetsManager::applyResourceChange(const keyToIdDomain[key] = id; data->emplace(lwt, resource, domain, key); + + lock->HashToId[resource.hash()] = {(EnumAssets) type, id}; } } @@ -511,6 +513,39 @@ AssetsManager::Out_applyResourceChange AssetsManager::applyResourceChange(const std::set_difference(l.begin(), l.end(), noc.begin(), noc.end(), std::back_inserter(result.Lost[type])); } + // Дамп ключей assets + { + std::stringstream result; + + auto lock = LocalObj.lock(); + for(int type = 0; type < (int) EnumAssets::MAX_ENUM; type++) { + if(type == 0) + result << "Nodestate:\n"; + else if(type == 1) + result << "Particle:\n"; + else if(type == 2) + result << "Animation:\n"; + else if(type == 3) + result << "Model:\n"; + else if(type == 4) + result << "Texture:\n"; + else if(type == 5) + result << "Sound:\n"; + else if(type == 6) + result << "Font:\n"; + + for(const auto& [domain, list] : lock->KeyToId[type]) { + result << "\t" << domain << ":\n"; + + for(const auto& [key, id] : list) { + result << "\t\t" << key << " = " << id << '\n'; + } + } + } + + LOG.debug() << "Дамп ассетов:\n" << result.str(); + } + if(!orr.Nodestates.empty()) { auto lock = LocalObj.lock(); @@ -617,6 +652,7 @@ AssetsManager::Out_applyResourceChange AssetsManager::applyResourceChange(const } } + entry.FullSubTextureDeps.append_range(entry.TextureDeps); { std::sort(entry.FullSubTextureDeps.begin(), entry.FullSubTextureDeps.end()); auto eraseIter = std::unique(entry.FullSubTextureDeps.begin(), entry.FullSubTextureDeps.end()); diff --git a/Src/Server/AssetsManager.hpp b/Src/Server/AssetsManager.hpp index 047f4d7..fe975e6 100644 --- a/Src/Server/AssetsManager.hpp +++ b/Src/Server/AssetsManager.hpp @@ -105,6 +105,7 @@ private: // Связь домены -> {ключ -> идентификатор} std::unordered_map> KeyToId[(int) EnumAssets::MAX_ENUM]; + std::unordered_map> HashToId; std::tuple&> nextId(EnumAssets type); @@ -132,6 +133,28 @@ private: return std::nullopt; } + std::optional> getResource(const Hash_t& hash) { + auto iter = HashToId.find(hash); + if(iter == HashToId.end()) + return std::nullopt; + + auto [type, id] = iter->second; + std::optional> res = getResource(type, id); + if(!res) { + HashToId.erase(iter); + return std::nullopt; + } + + if(std::get(*res).hash() == hash) { + auto& [resource, domain, key] = *res; + return std::tuple{resource, domain, key, type, id}; + } + + + HashToId.erase(iter); + return std::nullopt; + } + const std::optional>& getResourceNodestate(ResourceId id) { assert(id < Table_NodeState.size()*TableEntry::ChunkSize); return Table_NodeState[id / TableEntry::ChunkSize] @@ -224,6 +247,11 @@ public: return LocalObj.lock()->getResource(type, id); } + // Выдаёт ресурс по хешу + std::optional> getResource(const Hash_t& hash) { + return LocalObj.lock()->getResource(hash); + } + // Выдаёт зависимости к ресурсам профиля ноды std::tuple, std::vector> getNodeDependency(const std::string& domain, const std::string& key) diff --git a/Src/Server/GameServer.cpp b/Src/Server/GameServer.cpp index b876ac7..2a22ee0 100644 --- a/Src/Server/GameServer.cpp +++ b/Src/Server/GameServer.cpp @@ -806,14 +806,15 @@ void GameServer::BackingNoiseGenerator_t::run(int id) { std::array data; float *ptr = &data[0]; + std::fill(ptr, ptr+64*64*64, 0); - for(int z = 0; z < 64; z++) - for(int y = 0; y < 64; y++) - for(int x = 0; x < 64; x++, ptr++) { - // *ptr = TOS::genRand(); - *ptr = glm::perlin(glm::vec3(posNode.x+x, posNode.y+y, posNode.z+z) / 16.13f); - //*ptr = std::pow(*ptr, 0.75f)*1.5f; - } + // for(int z = 0; z < 64; z++) + // for(int y = 0; y < 64; y++) + // for(int x = 0; x < 64; x++, ptr++) { + // // *ptr = TOS::genRand(); + // *ptr = glm::perlin(glm::vec3(posNode.x+x, posNode.y+y, posNode.z+z) / 16.13f); + // //*ptr = std::pow(*ptr, 0.75f)*1.5f; + // } Output.lock()->push_back({key, std::move(data)}); } @@ -1493,7 +1494,7 @@ void GameServer::init(fs::path worldPath) { BackingNoiseGenerator.Threads[iter] = std::thread(&BackingNoiseGenerator_t::run, &BackingNoiseGenerator, iter); } - BackingAsyncLua.Threads.resize(4); + BackingAsyncLua.Threads.resize(1); for(size_t iter = 0; iter < BackingAsyncLua.Threads.size(); iter++) { BackingAsyncLua.Threads[iter] = std::thread(&BackingAsyncLua_t::run, &BackingAsyncLua, iter); } @@ -1837,12 +1838,8 @@ void GameServer::stepGeneratorAndLuaAsync(IWorldSaveBackend::TickSyncInfo_Out db // Обработка шума на стороне луа { std::vector>> calculatedNoise = BackingNoiseGenerator.tickSync(std::move(db.NotExisten)); - if(!calculatedNoise.empty()) { - auto lock = BackingAsyncLua.NoiseIn.lock(); - - for(auto& pair : calculatedNoise) - lock->push(pair); - } + if(!calculatedNoise.empty()) + BackingAsyncLua.NoiseIn.lock()->push_range(calculatedNoise); calculatedNoise.clear(); @@ -2408,7 +2405,15 @@ void GameServer::stepSyncContent() { auto& [resource, domain, key] = *result; resources.emplace_back((EnumAssets) type, resId, domain, key, resource); } - + } + + for(const Hash_t& hash : full.Hashes) { + std::optional> result = Content.AM.getResource(hash); + if(!result) + continue; + + auto& [resource, domain, key, type, id] = *result; + resources.emplace_back(type, id, domain, key, resource); } // Информируем о запрошенных профилях diff --git a/Src/Server/GameServer.hpp b/Src/Server/GameServer.hpp index bd0f0ae..6e5f4af 100644 --- a/Src/Server/GameServer.hpp +++ b/Src/Server/GameServer.hpp @@ -192,7 +192,7 @@ class GameServer : public AsyncObject { thread.join(); } - __attribute__((optimize("O3"))) void run(int id); + /* __attribute__((optimize("O3"))) */ void run(int id); } BackingChunkPressure; /* diff --git a/Src/Server/RemoteClient.cpp b/Src/Server/RemoteClient.cpp index fe9030e..30bd4c6 100644 --- a/Src/Server/RemoteClient.cpp +++ b/Src/Server/RemoteClient.cpp @@ -523,10 +523,12 @@ void RemoteClient::informateAssets(const std::vectorcheckPacketBorder(2+4+newForClient.size()*(1+4+32)); + lock->checkPacketBorder(2+1+4+newForClient.size()*(1+4+64+32)); lock->NextPacket << (uint8_t) ToClient::L1::Resource // Оповещение << ((uint8_t) ToClient::L2Resource::Bind) << uint32_t(newForClient.size()); for(auto& [type, resId, domain, key, hash, size] : newForClient) { // TODO: может внести ограничение на длину домена и ключа? - lock->NextPacket << uint8_t(type) << uint32_t(resId) << domain << key << size; + lock->NextPacket << uint8_t(type) << uint32_t(resId) << domain << key; lock->NextPacket.write((const std::byte*) hash.data(), hash.size()); } }