This commit is contained in:
2025-08-11 17:30:19 +06:00
parent efcf8daf7e
commit 9556e1affd
7 changed files with 162 additions and 18 deletions

View File

@@ -0,0 +1,11 @@
#include "AssetsManager.hpp"
namespace LV::Server {
coro<AssetsManager::Out_recheckResources> AssetsManager::recheckResources(AssetsRegister info) const {
}
}

View File

@@ -0,0 +1,116 @@
#pragma once
#include "Abstract.hpp"
#include "Common/Abstract.hpp"
#include "boost/asio/io_context.hpp"
#include "sha2.hpp"
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <filesystem>
#include <unordered_map>
namespace LV::Server {
namespace fs = std::filesystem;
class AssetsManager {
public:
struct Resource {
private:
struct Inline {
boost::interprocess::file_mapping MMap;
boost::interprocess::mapped_region Region;
Hash_t Hash;
Inline(fs::path path)
: MMap(path.c_str(), boost::interprocess::read_only),
Region(MMap, boost::interprocess::read_only)
{}
};
std::shared_ptr<Inline> In;
public:
Resource(fs::path path)
: In(std::make_shared<Inline>(path))
{
In->Hash = sha2::sha256((const uint8_t*) In->Region.get_address(), In->Region.get_size());
}
Resource(const Resource&) = default;
Resource(Resource&&) = default;
Resource& operator=(const Resource&) = default;
Resource& operator=(Resource&&) = default;
bool operator<=>(const Resource&) const = default;
const std::byte* data() const { return (const std::byte*) In->Region.get_address(); }
size_t size() const { return In->Region.get_size(); }
Hash_t hash() const { return In->Hash; }
};
private:
// Данные об отслеживаемых файлах
struct DataEntry {
// Время последнего изменения файла
size_t FileChangeTime;
Resource Res;
};
struct TableEntry {
bool IsFull = false;
std::bitset<4096> Empty;
std::array<std::optional<DataEntry>, 4096> Entries;
TableEntry() {
Empty.reset();
}
};
// Данные не меняются в процессе работы сервера.
// Изменения возможны при синхронизации всего сервера
// и перехода в режим перезагрузки модов
// Связь ресурсов по идентификаторам
std::vector<std::unique_ptr<TableEntry>> Table[(int) EnumAssets::MAX_ENUM];
// Связь домены -> {ключ -> идентификатор}
std::unordered_map<std::string, std::unordered_map<std::string, ResourceId_t>> KeyToId[(int) EnumAssets::MAX_ENUM];
DataEntry& getEntry(EnumAssets type, ResourceId_t id);
public:
AssetsManager(asio::io_context& ioc);
~AssetsManager();
/*
Перепроверка изменений ресурсов по дате изменения, пересчёт хешей.
Обнаруженные изменения должны быть отправлены всем клиентам.
Ресурсы будут обработаны в подходящий формат и сохранены в кеше.
Одновременно может выполнятся только одна такая функция
Используется в GameServer
*/
struct AssetsRegister {
/*
Пути до активных папок assets, соответствую порядку загруженным модам.
От последнего мода к первому.
Тот файл, что был загружен раньше и будет использоваться
*/
std::vector<fs::path> Assets;
/*
У этих ресурсов приоритет выше, если их удастся получить,
то использоваться будут именно они
*/
std::vector<std::tuple<std::string, EnumAssets, void*>> Custom;
};
struct Out_recheckResources {
std::vector<std::tuple< ResourceId_t, EnumAssets, Resource >> NewOrChange;
std::vector<std::tuple< ResourceId_t, EnumAssets >> Lost;
};
coro<Out_recheckResources> recheckResources(AssetsRegister) const;
};
}

View File

@@ -74,6 +74,7 @@ void BinaryResourceManager::run() {
if(var.index() == 0) {
std::shared_ptr<ResourceFile> resource = std::get<0>(var);
resource = convertFormate(resource, (EnumBinResource) type);
resource->calcHash();
return resource;
} else {
@@ -311,6 +312,10 @@ BinaryResourceManager::loadFile(const std::vector<fs::path>& assets, const std::
}
}
std::shared_ptr<ResourceFile> convertFormate(std::shared_ptr<ResourceFile> file, EnumBinResource type) {
return file;
}
BinaryResourceManager::BinaryResourceManager(asio::io_context &ioc)
: AsyncObject(ioc), Thread(&BinaryResourceManager::run, this)
{

View File

@@ -42,7 +42,7 @@ private:
// Поток сервера
// Последовательная регистрация ресурсов
ResourceId_t NextId[(int) EnumBinResource::MAX_ENUM] = {0};
ResourceId_t NextId[(int) EnumAssets::MAX_ENUM] = {0};
// Известные ресурсы, им присвоен идентификатор
// Нужно для потока загрузки
std::unordered_map<std::string, ResourceId_t> KnownResource[(int) EnumBinResource::MAX_ENUM];
@@ -76,6 +76,7 @@ private:
void run();
std::variant<std::shared_ptr<ResourceFile>, std::string>
loadFile(const std::vector<fs::path>& assets, const std::string& path, EnumBinResource type);
std::shared_ptr<ResourceFile> convertFormate(std::shared_ptr<ResourceFile> file, EnumBinResource type);
public:
// Если ресурс будет обновлён или загружен будет вызвано onResourceUpdate

View File

@@ -277,6 +277,7 @@ public:
Pos::Object CameraPos = {0, 0, 0};
ToServer::PacketQuat CameraQuat = {0};
TOS::SpinlockObject<std::queue<uint8_t>> Actions;
ResourceId_t RecievedAssets[(int) EnumAssets::MAX_ENUM] = {0};
public:
RemoteClient(asio::io_context &ioc, tcp::socket socket, const std::string username, std::vector<ResourceFile::Hash_t> &&client_cache)