From 4d6355298c65500f016368170099b8744f4934a1 Mon Sep 17 00:00:00 2001 From: DrSocalkwe3n Date: Fri, 15 Aug 2025 11:31:48 +0600 Subject: [PATCH] * --- Src/Server/Abstract.hpp | 18 ++-- Src/Server/RemoteClient.cpp | 4 - Src/Server/RemoteClient.hpp | 163 +++++++++++++----------------------- Src/Server/World.hpp | 1 - 4 files changed, 66 insertions(+), 120 deletions(-) diff --git a/Src/Server/Abstract.hpp b/Src/Server/Abstract.hpp index 2219278..d7c1298 100644 --- a/Src/Server/Abstract.hpp +++ b/Src/Server/Abstract.hpp @@ -29,9 +29,9 @@ using ClientFuncEntityId_t = RegionFuncEntityId_t; using ServerFuncEntityId_t = std::tuple; using MediaStreamId_t = uint16_t; -using ContentBridgeId_t = ResourceId_t; -using PlayerId_t = ResourceId_t; -using DefGeneratorId_t = ResourceId_t; +using ContentBridgeId_t = ResourceId; +using PlayerId_t = ResourceId; +using DefGeneratorId_t = ResourceId; /* @@ -59,10 +59,10 @@ struct ServerTime { struct VoxelCube_Region { union { struct { - DefVoxelId_t VoxelId : 24, Meta : 8; + DefVoxelId VoxelId : 24, Meta : 8; }; - DefVoxelId_t Data = 0; + DefVoxelId Data = 0; }; Pos::bvec1024u Left, Right; // TODO: заменить на позицию и размер @@ -229,13 +229,13 @@ struct DefNode_t { }; class Entity { - DefEntityId_t DefId; + DefEntityId DefId; public: LocalAABB ABBOX; // PosQuat - DefWorldId_t WorldId; + DefWorldId WorldId; Pos::Object Pos, Speed, Acceleration; glm::quat Quat; static constexpr uint16_t HP_BS = 4096, HP_BS_Bit = 12; @@ -255,13 +255,13 @@ public: IsRemoved = false; public: - Entity(DefEntityId_t defId); + Entity(DefEntityId defId); AABB aabbAtPos() { return {Pos-Pos::Object(ABBOX.x/2, ABBOX.y/2, ABBOX.z/2), Pos+Pos::Object(ABBOX.x/2, ABBOX.y/2, ABBOX.z/2)}; } - DefEntityId_t getDefId() const { return DefId; } + DefEntityId getDefId() const { return DefId; } }; template diff --git a/Src/Server/RemoteClient.cpp b/Src/Server/RemoteClient.cpp index 4957260..bf41eee 100644 --- a/Src/Server/RemoteClient.cpp +++ b/Src/Server/RemoteClient.cpp @@ -6,11 +6,7 @@ #include #include #include -#include #include -#include -#include -#include "World.hpp" #include diff --git a/Src/Server/RemoteClient.hpp b/Src/Server/RemoteClient.hpp index a8f8c52..026de0b 100644 --- a/Src/Server/RemoteClient.hpp +++ b/Src/Server/RemoteClient.hpp @@ -6,20 +6,18 @@ #include "Abstract.hpp" #include "Common/Packets.hpp" #include "Server/AssetsManager.hpp" -#include "Server/ContentEventController.hpp" -#include "assets.hpp" +#include "Server/ContentManager.hpp" #include -#include #include #include #include -#include #include #include -#include namespace LV::Server { +class World; + template= sizeof(ClientKey), int> = 0> class CSChunkedMapper { std::unordered_map, std::array>> Chunks; @@ -146,19 +144,19 @@ public: */ struct ResourceRequest { std::vector Hashes; - std::vector BinToHash[5 /*EnumBinResource*/]; + std::vector AssetsInfo[(int) EnumAssets::MAX_ENUM]; - std::vector Voxel; - std::vector Node; - std::vector World; - std::vector Portal; - std::vector Entity; - std::vector Item; + std::vector Voxel; + std::vector Node; + std::vector World; + std::vector Portal; + std::vector Entity; + std::vector Item; void insert(const ResourceRequest &obj) { Hashes.insert(Hashes.end(), obj.Hashes.begin(), obj.Hashes.end()); - for(int iter = 0; iter < 5; iter++) - BinToHash[iter].insert(BinToHash[iter].end(), obj.BinToHash[iter].begin(), obj.BinToHash[iter].end()); + for(int iter = 0; iter < (int) EnumAssets::MAX_ENUM; iter++) + AssetsInfo[iter].insert(AssetsInfo[iter].end(), obj.AssetsInfo[iter].begin(), obj.AssetsInfo[iter].end()); Voxel.insert(Voxel.end(), obj.Voxel.begin(), obj.Voxel.end()); Node.insert(Node.end(), obj.Node.begin(), obj.Node.end()); @@ -180,9 +178,9 @@ struct ResourceRequest { for(int type = 0; type < (int) EnumAssets::MAX_ENUM; type++) { - std::sort(BinToHash[type].begin(), BinToHash[type].end()); - auto last = std::unique(BinToHash[type].begin(), BinToHash[type].end()); - BinToHash[type].erase(last, BinToHash[type].end()); + std::sort(AssetsInfo[type].begin(), AssetsInfo[type].end()); + auto last = std::unique(AssetsInfo[type].begin(), AssetsInfo[type].end()); + AssetsInfo[type].erase(last, AssetsInfo[type].end()); } std::sort(Hashes.begin(), Hashes.end()); @@ -208,22 +206,11 @@ class RemoteClient { DestroyLock UseLock; Net::AsyncSocket Socket; bool IsConnected = true, IsGoingShutdown = false; - - std::vector ClientBinaryCache, // Хеши ресурсов которые есть у клиента - NeedToSend; // Хеши которые нужно получить и отправить - - /* - При обнаружении нового контента составляется запрос (ResourceRequest) - на полное описание ресурса. Это описание отправляется клиенту и используется - чтобы выстроить зависимость какие базовые ресурсы использует контент. - Если базовые ресурсы не известны, то они также запрашиваются. - */ struct NetworkAndResource_t { - struct ResUsesObj { + struct ResUses_t { // Счётчики использования двоичных кэшируемых ресурсов + хэш привязанный к идентификатору - std::map> AssetsUse[(int) EnumAssets::MAX_ENUM]; - + std::map AssetsUse[(int) EnumAssets::MAX_ENUM]; // Зависимость профилей контента от профилей ресурсов // Нужно чтобы пересчитать зависимости к профилям ресурсов @@ -274,20 +261,32 @@ class RemoteClient { }; std::map RefEntity; + void incrementBinary(const RefAssets_t& bin); + void decrementBinary(RefAssets_t&& bin); } ResUses; // Смена идентификаторов сервера на клиентские SCSKeyRemapper ReMapEntities; + // Запрос информации об ассетах и профилях контента + ResourceRequest NextRequest; + Net::Packet NextPacket; std::vector SimplePackets; - ResourceRequest NextRequest; }; struct { - // Ресурсы, отправленные на клиент в этой сессии - std::vector OnClient; - std::vector> ToSend; + /* + К концу такта собираются необходимые идентификаторы ресурсов + В конце такта сервер забирает запросы и возвращает информацию + о ресурсах. Отправляем связку Идентификатор + домен:ключ + + хеш. Если у клиента не окажется этого ресурса, он может его запросить + */ + + // Ресурсы, отправленные на клиент в этой сессии и запрошенные клиентом + std::vector OnClient, ClientRequested; + // Отправляемые на клиент ресурсы (в конце текущее смещение по отправке) + std::vector> ToSend; } AssetsInWork; TOS::SpinlockObject NetworkAndResource; @@ -306,9 +305,8 @@ public: public: RemoteClient(asio::io_context &ioc, tcp::socket socket, const std::string username, std::vector &&client_cache) - : LOG("RemoteClient " + username), Socket(ioc, std::move(socket)), Username(username), ClientBinaryCache(std::move(client_cache)) - { - } + : LOG("RemoteClient " + username), Socket(ioc, std::move(socket)), Username(username) + {} ~RemoteClient(); @@ -330,71 +328,33 @@ public: Сервер собирает изменения миров, сжимает их и раздаёт на отправку игрокам */ - // Функции подготавливают пакеты к отправке - // Отслеживаемое игроком использование контента - - TOS::Spinlock MurkyLock; - Net::Packet MurkyNextPacket; - std::vector MurkySimplePackets; - - void murkyCheckPacketBorder(uint16_t size) { - if(64000-MurkyNextPacket.size() < size || (MurkyNextPacket.size() != 0 && size == 0)) { - MurkySimplePackets.push_back(std::move(MurkyNextPacket)); - } - } - // marky используются в BackingChunkPressure_t в GameServer во время заморозки мира от записи. - // В это время просматриваются изменённые объекты и рассылаются изменения клиентам - - /* - Все пробегаются по игрокам, и смотрят наблюдаемые миры. - Если идентификатор мира % количество потоков == 0, то проверяем что - этот мир наблюдается игроком и готовим информацию о нём для отправки, - отправляем - - Синхронизация этапа с группой - - Потоки рассылки изменений соблюдают пакетность изменений. - Изменение чанков, потеря регионов, изменения чанков, потеря регионов - - игрок % потоки == 0 - Информируем о потерянных регионах - Информируем о потерянных мирах - - Синхронизация этапа с группой - */ - - /* - Использует пакеты - Используемые ресурсы - Запросы на ресурсы - - Объекты можно удалять когда это будет определено. - Потом при попытке отправить чанк будет проверка наблюдения - объекта клиентом - */ + // Все функции prepare потокобезопасные + // maybe используются в BackingChunkPressure_t в GameServer в пуле потоков. + // если возвращает false, то блокировка сейчас находится у другого потока + // и запрос не был обработан. // В зоне видимости добавился чанк или изменились его воксели - bool murky_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::u8string& compressed_voxels, + bool maybe_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::u8string& compressed_voxels, const std::vector& uniq_sorted_defines); // В зоне видимости добавился чанк или изменились его ноды - bool murky_prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::u8string& compressed_nodes, + bool maybe_prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::u8string& compressed_nodes, const std::vector& uniq_sorted_defines); // void prepareChunkUpdate_LightPrism(WorldId_t worldId, Pos::GlobalChunk chunkPos, const LightPrism *lights); - // Мир удалён из зоны видимости - void prepareWorldRemove(WorldId_t worldId); + // Клиент перестал наблюдать за сущностью + void prepareEntitiesRemove(const std::vector& entityId); // Регион удалён из зоны видимости void prepareRegionRemove(WorldId_t worldId, std::vector regionPoses); - // Клиент перестал наблюдать за сущностью - void prepareEntityRemove(ServerEntityId_t entityId); + // Мир удалён из зоны видимости + void prepareWorldRemove(WorldId_t worldId); // В зоне видимости добавилась новая сущность или она изменилась - void prepareEntityUpdate(ServerEntityId_t entityId, const Entity *entity); - void prepareEntityUpdate_Dynamic(ServerEntityId_t entityId, const Entity *entity); - // Мир появился в зоне видимости или изменился - void prepareWorldUpdate(WorldId_t worldId, World* world); + void prepareEntityUpdate(const std::vector>& entities); + void prepareEntityUpdate_Dynamic(const std::vector>& entities); // Наблюдаемая сущность пересекла границы региона, у неё изменился серверный идентификатор void prepareEntitySwap(ServerEntityId_t prevEntityId, ServerEntityId_t nextEntityId); + // Мир появился в зоне видимости или изменился + void prepareWorldUpdate(WorldId_t worldId, World* world); // В зоне видимости добавился порта или он изменился // void preparePortalUpdate(PortalId_t portalId, void* portal); @@ -411,20 +371,16 @@ public: // Сюда приходят все обновления ресурсов движка // Глобально их можно запросить в выдаче pushPreparedPackets() - // Оповещение о ресурсе для отправки клиентам - void informateBinary(const std::vector>& resources); - - // Привязывает локальный идентификатор с хешем. Если его нет у клиента, - // то делается запрос на получение ресурсы для последующей отправки клиенту - void informateIdToHash(const std::unordered_map* resourcesLink); + // Оповещение о запрошенных (и не только) ассетах + void informateAssets(const std::vector>& resources); // Игровые определения - void informateDefVoxel(const std::unordered_map &voxels); - void informateDefNode(const std::unordered_map &nodes); - void informateDefWorld(const std::unordered_map &worlds); - void informateDefPortal(const std::unordered_map &portals); - void informateDefEntity(const std::unordered_map &entityes); - void informateDefItem(const std::unordered_map &items); + void informateDefVoxel(const std::unordered_map &voxels); + void informateDefNode(const std::unordered_map &nodes); + void informateDefWorld(const std::unordered_map &worlds); + void informateDefPortal(const std::unordered_map &portals); + void informateDefEntity(const std::unordered_map &entityes); + void informateDefItem(const std::unordered_map &items); private: void checkPacketBorder(uint16_t size); @@ -432,17 +388,12 @@ private: coro<> readPacket(Net::AsyncSocket &sock); coro<> rP_System(Net::AsyncSocket &sock); - void incrementBinary(const ResUsesObj::RefDefBin_t& bin); - void decrementBinary(ResUsesObj::RefDefBin_t&& bin); - // void incrementProfile(const std::vector &textures, const std::vector &model, // const std::vector &sounds, const std::vector &font // ); // void decrementProfile(std::vector &&textures, std::vector &&model, // std::vector &&sounds, std::vector &&font // ); - - }; diff --git a/Src/Server/World.hpp b/Src/Server/World.hpp index 6871674..04ea712 100644 --- a/Src/Server/World.hpp +++ b/Src/Server/World.hpp @@ -2,7 +2,6 @@ #include "Common/Abstract.hpp" #include "Server/Abstract.hpp" -#include "Server/ContentEventController.hpp" #include "Server/SaveBackend.hpp" #include #include