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,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;
};
}