Files
LuaVox/Src/Server/AssetsManager.hpp
2025-08-11 17:30:19 +06:00

116 lines
4.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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