*
This commit is contained in:
@@ -68,13 +68,9 @@ void RemoteClient::shutdown(EnumDisconnect type, const std::string reason) {
|
|||||||
LOG.info() << "Игрок '" << Username << "' отключился " << info;
|
LOG.info() << "Игрок '" << Username << "' отключился " << info;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RemoteClient::maybe_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::u8string& compressed_voxels,
|
void RemoteClient::murky_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::u8string& compressed_voxels,
|
||||||
const std::vector<DefVoxelId_t>& uniq_sorted_defines)
|
const std::vector<DefVoxelId>& uniq_sorted_defines)
|
||||||
{
|
{
|
||||||
bool lock = ResUses.RefChunkLock.exchange(1);
|
|
||||||
if(lock)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Pos::bvec4u localChunk = chunkPos & 0x3;
|
Pos::bvec4u localChunk = chunkPos & 0x3;
|
||||||
Pos::GlobalRegion regionPos = chunkPos >> 2;
|
Pos::GlobalRegion regionPos = chunkPos >> 2;
|
||||||
|
|
||||||
@@ -84,12 +80,12 @@ bool RemoteClient::maybe_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::Globa
|
|||||||
Отправить всё клиенту
|
Отправить всё клиенту
|
||||||
*/
|
*/
|
||||||
|
|
||||||
std::vector<DefVoxelId_t>
|
std::vector<DefVoxelId>
|
||||||
newTypes, /* Новые типы вокселей */
|
newTypes, /* Новые типы вокселей */
|
||||||
lostTypes /* Потерянные типы вокселей */;
|
lostTypes /* Потерянные типы вокселей */;
|
||||||
|
|
||||||
// Отметим использование этих вокселей
|
// Отметим использование этих вокселей
|
||||||
for(const DefVoxelId_t& id : uniq_sorted_defines) {
|
for(const DefVoxelId& id : uniq_sorted_defines) {
|
||||||
auto iter = ResUses.DefVoxel.find(id);
|
auto iter = ResUses.DefVoxel.find(id);
|
||||||
if(iter == ResUses.DefVoxel.end()) {
|
if(iter == ResUses.DefVoxel.end()) {
|
||||||
// Новый тип
|
// Новый тип
|
||||||
@@ -109,7 +105,7 @@ bool RemoteClient::maybe_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::Globa
|
|||||||
auto iterRegion = iterWorld->second.find(regionPos);
|
auto iterRegion = iterWorld->second.find(regionPos);
|
||||||
if(iterRegion != iterWorld->second.end()) {
|
if(iterRegion != iterWorld->second.end()) {
|
||||||
// Уменьшим счётчик зависимостей
|
// Уменьшим счётчик зависимостей
|
||||||
for(const DefVoxelId_t& id : iterRegion->second[localChunk.pack()].Voxel) {
|
for(const DefVoxelId& id : iterRegion->second[localChunk.pack()].Voxel) {
|
||||||
auto iter = ResUses.DefVoxel.find(id);
|
auto iter = ResUses.DefVoxel.find(id);
|
||||||
assert(iter != ResUses.DefVoxel.end()); // Воксель должен быть в зависимостях
|
assert(iter != ResUses.DefVoxel.end()); // Воксель должен быть в зависимостях
|
||||||
if(--iter->second == 0) {
|
if(--iter->second == 0) {
|
||||||
@@ -129,12 +125,12 @@ bool RemoteClient::maybe_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::Globa
|
|||||||
if(!newTypes.empty()) {
|
if(!newTypes.empty()) {
|
||||||
// Добавляем новые типы в запрос
|
// Добавляем новые типы в запрос
|
||||||
NextRequest.Voxel.insert(NextRequest.Voxel.end(), newTypes.begin(), newTypes.end());
|
NextRequest.Voxel.insert(NextRequest.Voxel.end(), newTypes.begin(), newTypes.end());
|
||||||
for(DefVoxelId_t voxel : newTypes)
|
for(DefVoxelId voxel : newTypes)
|
||||||
ResUses.RefDefVoxel[voxel] = {};
|
ResUses.RefDefVoxel[voxel] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!lostTypes.empty()) {
|
if(!lostTypes.empty()) {
|
||||||
for(const DefVoxelId_t& id : lostTypes) {
|
for(const DefVoxelId& id : lostTypes) {
|
||||||
auto iter = ResUses.RefDefVoxel.find(id);
|
auto iter = ResUses.RefDefVoxel.find(id);
|
||||||
assert(iter != ResUses.RefDefVoxel.end()); // Должны быть описаны зависимости вокселя
|
assert(iter != ResUses.RefDefVoxel.end()); // Должны быть описаны зависимости вокселя
|
||||||
decrementBinary(std::move(iter->second));
|
decrementBinary(std::move(iter->second));
|
||||||
@@ -147,32 +143,25 @@ bool RemoteClient::maybe_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::Globa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkPacketBorder(4+4+8+2+4+compressed_voxels.size());
|
murkyCheckPacketBorder(4+4+8+2+4+compressed_voxels.size());
|
||||||
NextPacket << (uint8_t) ToClient::L1::Content
|
MurkyNextPacket << (uint8_t) ToClient::L1::Content
|
||||||
<< (uint8_t) ToClient::L2Content::ChunkVoxels
|
<< (uint8_t) ToClient::L2Content::ChunkVoxels
|
||||||
<< worldId << chunkPos.pack() << uint32_t(compressed_voxels.size());
|
<< worldId << chunkPos.pack() << uint32_t(compressed_voxels.size());
|
||||||
NextPacket.write((const std::byte*) compressed_voxels.data(), compressed_voxels.size());
|
MurkyNextPacket.write((const std::byte*) compressed_voxels.data(), compressed_voxels.size());
|
||||||
|
|
||||||
ResUses.RefChunkLock.exchange(0);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RemoteClient::maybe_prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::u8string& compressed_nodes,
|
void RemoteClient::maybe_prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::u8string& compressed_nodes,
|
||||||
const std::vector<DefNodeId_t>& uniq_sorted_defines)
|
const std::vector<DefNodeId>& uniq_sorted_defines)
|
||||||
{
|
{
|
||||||
bool lock = ResUses.RefChunkLock.exchange(1);
|
|
||||||
if(lock)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Pos::bvec4u localChunk = chunkPos & 0x3;
|
Pos::bvec4u localChunk = chunkPos & 0x3;
|
||||||
Pos::GlobalRegion regionPos = chunkPos >> 2;
|
Pos::GlobalRegion regionPos = chunkPos >> 2;
|
||||||
|
|
||||||
std::vector<DefNodeId_t>
|
std::vector<DefNodeId>
|
||||||
newTypes, /* Новые типы нод */
|
newTypes, /* Новые типы нод */
|
||||||
lostTypes /* Потерянные типы нод */;
|
lostTypes /* Потерянные типы нод */;
|
||||||
|
|
||||||
// Отметим использование этих нод
|
// Отметим использование этих нод
|
||||||
for(const DefNodeId_t& id : uniq_sorted_defines) {
|
for(const DefNodeId& id : uniq_sorted_defines) {
|
||||||
auto iter = ResUses.DefNode.find(id);
|
auto iter = ResUses.DefNode.find(id);
|
||||||
if(iter == ResUses.DefNode.end()) {
|
if(iter == ResUses.DefNode.end()) {
|
||||||
// Новый тип
|
// Новый тип
|
||||||
@@ -192,7 +181,7 @@ bool RemoteClient::maybe_prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::Global
|
|||||||
auto iterRegion = iterWorld->second.find(regionPos);
|
auto iterRegion = iterWorld->second.find(regionPos);
|
||||||
if(iterRegion != iterWorld->second.end()) {
|
if(iterRegion != iterWorld->second.end()) {
|
||||||
// Уменьшим счётчик зависимостей
|
// Уменьшим счётчик зависимостей
|
||||||
for(const DefNodeId_t& id : iterRegion->second[localChunk.pack()].Node) {
|
for(const DefNodeId& id : iterRegion->second[localChunk.pack()].Node) {
|
||||||
auto iter = ResUses.DefNode.find(id);
|
auto iter = ResUses.DefNode.find(id);
|
||||||
assert(iter != ResUses.DefNode.end()); // Нода должна быть в зависимостях
|
assert(iter != ResUses.DefNode.end()); // Нода должна быть в зависимостях
|
||||||
if(--iter->second == 0) {
|
if(--iter->second == 0) {
|
||||||
@@ -212,38 +201,35 @@ bool RemoteClient::maybe_prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::Global
|
|||||||
if(!newTypes.empty()) {
|
if(!newTypes.empty()) {
|
||||||
// Добавляем новые типы в запрос
|
// Добавляем новые типы в запрос
|
||||||
NextRequest.Node.insert(NextRequest.Node.end(), newTypes.begin(), newTypes.end());
|
NextRequest.Node.insert(NextRequest.Node.end(), newTypes.begin(), newTypes.end());
|
||||||
for(DefNodeId_t node : newTypes)
|
for(DefNodeId node : newTypes)
|
||||||
ResUses.RefDefNode[node] = {};
|
ResUses.RefDefNode[node] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!lostTypes.empty()) {
|
if(!lostTypes.empty()) {
|
||||||
for(const DefNodeId_t& id : lostTypes) {
|
for(const DefNodeId& id : lostTypes) {
|
||||||
auto iter = ResUses.RefDefNode.find(id);
|
auto iter = ResUses.RefDefNode.find(id);
|
||||||
assert(iter != ResUses.RefDefNode.end()); // Должны быть описаны зависимости ноды
|
assert(iter != ResUses.RefDefNode.end()); // Должны быть описаны зависимости ноды
|
||||||
decrementBinary(std::move(iter->second));
|
decrementBinary(std::move(iter->second));
|
||||||
ResUses.RefDefNode.erase(iter);
|
ResUses.RefDefNode.erase(iter);
|
||||||
|
|
||||||
checkPacketBorder(16);
|
checkPacketBorder(16);
|
||||||
NextPacket << (uint8_t) ToClient::L1::Definition
|
MurkyNextPacket << (uint8_t) ToClient::L1::Definition
|
||||||
<< (uint8_t) ToClient::L2Definition::FreeNode
|
<< (uint8_t) ToClient::L2Definition::FreeNode
|
||||||
<< id;
|
<< id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkPacketBorder(4+4+8+4+compressed_nodes.size());
|
checkPacketBorder(4+4+8+4+compressed_nodes.size());
|
||||||
NextPacket << (uint8_t) ToClient::L1::Content
|
MurkyNextPacket << (uint8_t) ToClient::L1::Content
|
||||||
<< (uint8_t) ToClient::L2Content::ChunkNodes
|
<< (uint8_t) ToClient::L2Content::ChunkNodes
|
||||||
<< worldId << chunkPos.pack() << uint32_t(compressed_nodes.size());
|
<< worldId << chunkPos.pack() << uint32_t(compressed_nodes.size());
|
||||||
NextPacket.write((const std::byte*) compressed_nodes.data(), compressed_nodes.size());
|
MurkyNextPacket.write((const std::byte*) compressed_nodes.data(), compressed_nodes.size());
|
||||||
|
|
||||||
ResUses.RefChunkLock.exchange(0);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteClient::prepareRegionRemove(WorldId_t worldId, Pos::GlobalRegion regionPos) {
|
void RemoteClient::prepareRegionRemove(WorldId_t worldId, Pos::GlobalRegion regionPos) {
|
||||||
std::vector<DefVoxelId_t>
|
std::vector<DefVoxelId>
|
||||||
lostTypesV /* Потерянные типы вокселей */;
|
lostTypesV /* Потерянные типы вокселей */;
|
||||||
std::vector<DefNodeId_t>
|
std::vector<DefNodeId>
|
||||||
lostTypesN /* Потерянные типы нод */;
|
lostTypesN /* Потерянные типы нод */;
|
||||||
|
|
||||||
// Уменьшаем зависимости вокселей и нод
|
// Уменьшаем зависимости вокселей и нод
|
||||||
@@ -257,7 +243,7 @@ void RemoteClient::prepareRegionRemove(WorldId_t worldId, Pos::GlobalRegion regi
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for(const auto &iterChunk : iterRegion->second) {
|
for(const auto &iterChunk : iterRegion->second) {
|
||||||
for(const DefVoxelId_t& id : iterChunk.Voxel) {
|
for(const DefVoxelId& id : iterChunk.Voxel) {
|
||||||
auto iter = ResUses.DefVoxel.find(id);
|
auto iter = ResUses.DefVoxel.find(id);
|
||||||
assert(iter != ResUses.DefVoxel.end()); // Воксель должен быть в зависимостях
|
assert(iter != ResUses.DefVoxel.end()); // Воксель должен быть в зависимостях
|
||||||
if(--iter->second == 0) {
|
if(--iter->second == 0) {
|
||||||
@@ -267,7 +253,7 @@ void RemoteClient::prepareRegionRemove(WorldId_t worldId, Pos::GlobalRegion regi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const DefNodeId_t& id : iterChunk.Node) {
|
for(const DefNodeId& id : iterChunk.Node) {
|
||||||
auto iter = ResUses.DefNode.find(id);
|
auto iter = ResUses.DefNode.find(id);
|
||||||
assert(iter != ResUses.DefNode.end()); // Нода должна быть в зависимостях
|
assert(iter != ResUses.DefNode.end()); // Нода должна быть в зависимостях
|
||||||
if(--iter->second == 0) {
|
if(--iter->second == 0) {
|
||||||
@@ -282,7 +268,7 @@ void RemoteClient::prepareRegionRemove(WorldId_t worldId, Pos::GlobalRegion regi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!lostTypesV.empty()) {
|
if(!lostTypesV.empty()) {
|
||||||
for(const DefVoxelId_t& id : lostTypesV) {
|
for(const DefVoxelId& id : lostTypesV) {
|
||||||
auto iter = ResUses.RefDefVoxel.find(id);
|
auto iter = ResUses.RefDefVoxel.find(id);
|
||||||
assert(iter != ResUses.RefDefVoxel.end()); // Должны быть описаны зависимости вокселя
|
assert(iter != ResUses.RefDefVoxel.end()); // Должны быть описаны зависимости вокселя
|
||||||
decrementBinary(std::move(iter->second));
|
decrementBinary(std::move(iter->second));
|
||||||
@@ -296,7 +282,7 @@ void RemoteClient::prepareRegionRemove(WorldId_t worldId, Pos::GlobalRegion regi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!lostTypesN.empty()) {
|
if(!lostTypesN.empty()) {
|
||||||
for(const DefNodeId_t& id : lostTypesN) {
|
for(const DefNodeId& id : lostTypesN) {
|
||||||
auto iter = ResUses.RefDefNode.find(id);
|
auto iter = ResUses.RefDefNode.find(id);
|
||||||
assert(iter != ResUses.RefDefNode.end()); // Должны быть описаны зависимости ноды
|
assert(iter != ResUses.RefDefNode.end()); // Должны быть описаны зависимости ноды
|
||||||
decrementBinary(std::move(iter->second));
|
decrementBinary(std::move(iter->second));
|
||||||
@@ -564,10 +550,10 @@ void RemoteClient::informateIdToHash(const std::unordered_map<ResourceId_t, Reso
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteClient::informateDefVoxel(const std::unordered_map<DefVoxelId_t, DefVoxel_t*> &voxels)
|
void RemoteClient::informateDefVoxel(const std::unordered_map<DefVoxelId, DefVoxel_t*> &voxels)
|
||||||
{
|
{
|
||||||
for(auto pair : voxels) {
|
for(auto pair : voxels) {
|
||||||
DefVoxelId_t id = pair.first;
|
DefVoxelId id = pair.first;
|
||||||
if(!ResUses.DefVoxel.contains(id))
|
if(!ResUses.DefVoxel.contains(id))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -577,7 +563,7 @@ void RemoteClient::informateDefVoxel(const std::unordered_map<DefVoxelId_t, DefV
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteClient::informateDefNode(const std::unordered_map<DefNodeId_t, DefNode_t*> &nodes)
|
void RemoteClient::informateDefNode(const std::unordered_map<DefNodeId, DefNode_t*> &nodes)
|
||||||
{
|
{
|
||||||
for(auto& [id, def] : nodes) {
|
for(auto& [id, def] : nodes) {
|
||||||
if(!ResUses.DefNode.contains(id))
|
if(!ResUses.DefNode.contains(id))
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
#include <Common/Net.hpp>
|
#include <Common/Net.hpp>
|
||||||
#include "Abstract.hpp"
|
#include "Abstract.hpp"
|
||||||
#include "Common/Packets.hpp"
|
#include "Common/Packets.hpp"
|
||||||
|
#include "Server/AssetsManager.hpp"
|
||||||
#include "Server/ContentEventController.hpp"
|
#include "Server/ContentEventController.hpp"
|
||||||
|
#include "assets.hpp"
|
||||||
#include <Common/Abstract.hpp>
|
#include <Common/Abstract.hpp>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
@@ -137,13 +139,17 @@ public:
|
|||||||
состоянии для клиента и шаблоны, которые клиенту уже не нужны.
|
состоянии для клиента и шаблоны, которые клиенту уже не нужны.
|
||||||
Соответствующие менеджеры ресурсов будут следить за изменениями
|
Соответствующие менеджеры ресурсов будут следить за изменениями
|
||||||
этих ресурсов и переотправлять их клиенту
|
этих ресурсов и переотправлять их клиенту
|
||||||
|
|
||||||
|
Информация о двоичных ресурсах будет получена сразу же при их запросе.
|
||||||
|
Действительная отправка ресурсов будет только по запросу клиента.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
struct ResourceRequest {
|
struct ResourceRequest {
|
||||||
std::vector<Hash_t> Hashes;
|
std::vector<Hash_t> Hashes;
|
||||||
std::vector<ResourceId_t> BinToHash[5 /*EnumBinResource*/];
|
std::vector<ResourceId> BinToHash[5 /*EnumBinResource*/];
|
||||||
|
|
||||||
std::vector<DefVoxelId_t> Voxel;
|
std::vector<DefVoxelId> Voxel;
|
||||||
std::vector<DefNodeId_t> Node;
|
std::vector<DefNodeId> Node;
|
||||||
std::vector<DefWorldId_t> World;
|
std::vector<DefWorldId_t> World;
|
||||||
std::vector<DefPortalId_t> Portal;
|
std::vector<DefPortalId_t> Portal;
|
||||||
std::vector<DefEntityId_t> Entity;
|
std::vector<DefEntityId_t> Entity;
|
||||||
@@ -163,7 +169,7 @@ struct ResourceRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void uniq() {
|
void uniq() {
|
||||||
for(std::vector<ResourceId_t> *vec : {&Voxel, &Node, &World,
|
for(std::vector<ResourceId> *vec : {&Voxel, &Node, &World,
|
||||||
&Portal, &Entity, &Item
|
&Portal, &Entity, &Item
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
@@ -172,7 +178,7 @@ struct ResourceRequest {
|
|||||||
vec->erase(last, vec->end());
|
vec->erase(last, vec->end());
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int type = 0; type < (int) EnumBinResource::MAX_ENUM; type++)
|
for(int type = 0; type < (int) EnumAssets::MAX_ENUM; type++)
|
||||||
{
|
{
|
||||||
std::sort(BinToHash[type].begin(), BinToHash[type].end());
|
std::sort(BinToHash[type].begin(), BinToHash[type].end());
|
||||||
auto last = std::unique(BinToHash[type].begin(), BinToHash[type].end());
|
auto last = std::unique(BinToHash[type].begin(), BinToHash[type].end());
|
||||||
@@ -213,71 +219,85 @@ class RemoteClient {
|
|||||||
Если базовые ресурсы не известны, то они также запрашиваются.
|
Если базовые ресурсы не известны, то они также запрашиваются.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct ResUsesObj {
|
struct NetworkAndResource_t {
|
||||||
// Счётчики использования двоичных кэшируемых ресурсов + хэш привязанный к идентификатору
|
struct ResUsesObj {
|
||||||
std::map<ResourceId_t, std::tuple<uint32_t, Hash_t>> BinUse[5];
|
// Счётчики использования двоичных кэшируемых ресурсов + хэш привязанный к идентификатору
|
||||||
|
std::map<ResourceId, std::tuple<uint32_t, Hash_t>> AssetsUse[(int) EnumAssets::MAX_ENUM];
|
||||||
// Счётчики использование профилей контента
|
|
||||||
std::map<DefVoxelId_t, uint32_t> DefVoxel; // Один чанк, одно использование
|
|
||||||
std::map<DefNodeId_t, uint32_t> DefNode;
|
|
||||||
std::map<DefWorldId_t, uint32_t> DefWorld;
|
|
||||||
std::map<DefPortalId_t, uint32_t> DefPortal;
|
|
||||||
std::map<DefEntityId_t, uint32_t> DefEntity;
|
|
||||||
std::map<DefItemId_t, uint32_t> DefItem; // При передаче инвентарей?
|
|
||||||
|
|
||||||
// Зависимость профилей контента от профилей ресурсов
|
|
||||||
// Нужно чтобы пересчитать зависимости к профилям ресурсов
|
|
||||||
struct RefDefBin_t {
|
|
||||||
std::vector<ResourceId_t> Resources[5];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
std::map<DefVoxelId_t, RefDefBin_t> RefDefVoxel;
|
// Зависимость профилей контента от профилей ресурсов
|
||||||
std::map<DefNodeId_t, RefDefBin_t> RefDefNode;
|
// Нужно чтобы пересчитать зависимости к профилям ресурсов
|
||||||
std::map<WorldId_t, RefDefBin_t> RefDefWorld;
|
struct RefAssets_t {
|
||||||
std::map<DefPortalId_t, RefDefBin_t> RefDefPortal;
|
std::vector<ResourceId> Resources[(int) EnumAssets::MAX_ENUM];
|
||||||
std::map<DefEntityId_t, RefDefBin_t> RefDefEntity;
|
};
|
||||||
std::map<DefItemId_t, RefDefBin_t> RefDefItem;
|
|
||||||
|
|
||||||
// Модификационные зависимости экземпляров профилей контента
|
std::map<DefVoxelId, RefAssets_t> RefDefVoxel;
|
||||||
struct ChunkRef {
|
std::map<DefNodeId, RefAssets_t> RefDefNode;
|
||||||
// Отсортированные списки уникальных вокселей
|
std::map<WorldId_t, RefAssets_t> RefDefWorld;
|
||||||
std::vector<DefVoxelId_t> Voxel;
|
std::map<DefPortalId, RefAssets_t> RefDefPortal;
|
||||||
std::vector<DefNodeId_t> Node;
|
std::map<DefEntityId, RefAssets_t> RefDefEntity;
|
||||||
};
|
std::map<DefItemId, RefAssets_t> RefDefItem;
|
||||||
std::atomic_bool RefChunkLock = 0;
|
|
||||||
std::map<WorldId_t, std::map<Pos::GlobalRegion, std::array<ChunkRef, 4*4*4>>> RefChunk;
|
|
||||||
struct RefWorld_t {
|
|
||||||
DefWorldId_t Profile;
|
|
||||||
};
|
|
||||||
std::map<WorldId_t, RefWorld_t> RefWorld;
|
|
||||||
struct RefPortal_t {
|
|
||||||
DefPortalId_t Profile;
|
|
||||||
};
|
|
||||||
std::map<PortalId_t, RefPortal_t> RefPortal;
|
|
||||||
struct RefEntity_t {
|
|
||||||
DefEntityId_t Profile;
|
|
||||||
};
|
|
||||||
std::map<ServerEntityId_t, RefEntity_t> RefEntity;
|
|
||||||
|
|
||||||
} ResUses;
|
// Счётчики использование профилей контента
|
||||||
|
std::map<DefVoxelId, uint32_t> DefVoxel; // Один чанк, одно использование
|
||||||
|
std::map<DefNodeId, uint32_t> DefNode;
|
||||||
|
std::map<DefWorldId, uint32_t> DefWorld;
|
||||||
|
std::map<DefPortalId, uint32_t> DefPortal;
|
||||||
|
std::map<DefEntityId, uint32_t> DefEntity;
|
||||||
|
std::map<DefItemId, uint32_t> DefItem; // При передаче инвентарей?
|
||||||
|
|
||||||
|
|
||||||
|
// Зависимость наблюдаемых чанков от профилей нод и вокселей
|
||||||
|
struct ChunkRef {
|
||||||
|
// Отсортированные списки уникальных вокселей
|
||||||
|
std::vector<DefVoxelId> Voxel;
|
||||||
|
std::vector<DefNodeId> Node;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<WorldId_t, std::map<Pos::GlobalRegion, std::array<ChunkRef, 4*4*4>>> RefChunk;
|
||||||
|
|
||||||
|
// Модификационные зависимости экземпляров профилей контента
|
||||||
|
// У сущностей в мире могут дополнительно изменятся свойства, переписывая их профиль
|
||||||
|
struct RefWorld_t {
|
||||||
|
DefWorldId Profile;
|
||||||
|
RefAssets_t Assets;
|
||||||
|
};
|
||||||
|
std::map<WorldId_t, RefWorld_t> RefWorld;
|
||||||
|
struct RefPortal_t {
|
||||||
|
DefPortalId Profile;
|
||||||
|
RefAssets_t Assets;
|
||||||
|
};
|
||||||
|
// std::map<PortalId, RefPortal_t> RefPortal;
|
||||||
|
struct RefEntity_t {
|
||||||
|
DefEntityId Profile;
|
||||||
|
RefAssets_t Assets;
|
||||||
|
};
|
||||||
|
std::map<ServerEntityId_t, RefEntity_t> RefEntity;
|
||||||
|
|
||||||
|
} ResUses;
|
||||||
|
|
||||||
|
// Смена идентификаторов сервера на клиентские
|
||||||
|
SCSKeyRemapper<ServerEntityId_t, ClientEntityId_t> ReMapEntities;
|
||||||
|
|
||||||
|
Net::Packet NextPacket;
|
||||||
|
std::vector<Net::Packet> SimplePackets;
|
||||||
|
ResourceRequest NextRequest;
|
||||||
|
};
|
||||||
|
|
||||||
// Смена идентификаторов сервера на клиентские
|
|
||||||
struct {
|
struct {
|
||||||
SCSKeyRemapper<ServerEntityId_t, ClientEntityId_t> Entityes;
|
// Ресурсы, отправленные на клиент в этой сессии
|
||||||
SCSKeyRemapper<ServerFuncEntityId_t, ClientEntityId_t> FuncEntityes;
|
std::vector<Hash_t> OnClient;
|
||||||
} ResRemap;
|
std::vector<std::tuple<EnumAssets, ResourceId, AssetsManager::Resource>> ToSend;
|
||||||
|
} AssetsInWork;
|
||||||
|
|
||||||
Net::Packet NextPacket;
|
TOS::SpinlockObject<NetworkAndResource_t> NetworkAndResource;
|
||||||
std::vector<Net::Packet> SimplePackets;
|
|
||||||
ResourceRequest NextRequest;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const std::string Username;
|
const std::string Username;
|
||||||
Pos::Object CameraPos = {0, 0, 0};
|
Pos::Object CameraPos = {0, 0, 0};
|
||||||
ToServer::PacketQuat CameraQuat = {0};
|
ToServer::PacketQuat CameraQuat = {0};
|
||||||
TOS::SpinlockObject<std::queue<uint8_t>> Actions;
|
TOS::SpinlockObject<std::queue<uint8_t>> Actions;
|
||||||
ResourceId_t RecievedAssets[(int) EnumAssets::MAX_ENUM] = {0};
|
ResourceId RecievedAssets[(int) EnumAssets::MAX_ENUM] = {0};
|
||||||
|
|
||||||
// Регионы, наблюдаемые клиентом
|
// Регионы, наблюдаемые клиентом
|
||||||
ContentViewInfo ContentViewState;
|
ContentViewInfo ContentViewState;
|
||||||
@@ -303,6 +323,9 @@ public:
|
|||||||
Socket.pushPackets(simplePackets, smartPackets);
|
Socket.pushPackets(simplePackets, smartPackets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Возвращает список точек наблюдений клиентом с радиусом в регионах
|
||||||
|
std::vector<std::tuple<WorldId_t, Pos::Object, uint8_t>> getViewPoints();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Сервер собирает изменения миров, сжимает их и раздаёт на отправку игрокам
|
Сервер собирает изменения миров, сжимает их и раздаёт на отправку игрокам
|
||||||
*/
|
*/
|
||||||
@@ -311,6 +334,14 @@ public:
|
|||||||
// Отслеживаемое игроком использование контента
|
// Отслеживаемое игроком использование контента
|
||||||
|
|
||||||
TOS::Spinlock MurkyLock;
|
TOS::Spinlock MurkyLock;
|
||||||
|
Net::Packet MurkyNextPacket;
|
||||||
|
std::vector<Net::Packet> 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 во время заморозки мира от записи.
|
// marky используются в BackingChunkPressure_t в GameServer во время заморозки мира от записи.
|
||||||
// В это время просматриваются изменённые объекты и рассылаются изменения клиентам
|
// В это время просматриваются изменённые объекты и рассылаются изменения клиентам
|
||||||
|
|
||||||
@@ -332,26 +363,38 @@ public:
|
|||||||
Синхронизация этапа с группой
|
Синхронизация этапа с группой
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Использует пакеты
|
||||||
|
Используемые ресурсы
|
||||||
|
Запросы на ресурсы
|
||||||
|
|
||||||
|
Объекты можно удалять когда это будет определено.
|
||||||
|
Потом при попытке отправить чанк будет проверка наблюдения
|
||||||
|
объекта клиентом
|
||||||
|
*/
|
||||||
|
|
||||||
// В зоне видимости добавился чанк или изменились его воксели
|
// В зоне видимости добавился чанк или изменились его воксели
|
||||||
void murky_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::u8string& compressed_voxels,
|
bool murky_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::u8string& compressed_voxels,
|
||||||
const std::vector<DefVoxelId_t>& uniq_sorted_defines);
|
const std::vector<DefVoxelId>& uniq_sorted_defines);
|
||||||
// В зоне видимости добавился чанк или изменились его ноды
|
// В зоне видимости добавился чанк или изменились его ноды
|
||||||
void murky_prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::u8string& compressed_nodes,
|
bool murky_prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::u8string& compressed_nodes,
|
||||||
const std::vector<DefNodeId_t>& uniq_sorted_defines);
|
const std::vector<DefNodeId>& uniq_sorted_defines);
|
||||||
// void prepareChunkUpdate_LightPrism(WorldId_t worldId, Pos::GlobalChunk chunkPos, const LightPrism *lights);
|
// void prepareChunkUpdate_LightPrism(WorldId_t worldId, Pos::GlobalChunk chunkPos, const LightPrism *lights);
|
||||||
// Регион удалён из зоны видимости
|
|
||||||
void murky_prepareRegionRemove(WorldId_t worldId, std::vector<Pos::GlobalRegion> regionPoses);
|
|
||||||
// Мир появился в зоне видимости
|
|
||||||
void murky_prepareWorldUpdate(WorldId_t worldId, World* world);
|
|
||||||
// Мир удалён из зоны видимости
|
// Мир удалён из зоны видимости
|
||||||
void murky_prepareWorldRemove(WorldId_t worldId);
|
void prepareWorldRemove(WorldId_t worldId);
|
||||||
|
// Регион удалён из зоны видимости
|
||||||
|
void prepareRegionRemove(WorldId_t worldId, std::vector<Pos::GlobalRegion> regionPoses);
|
||||||
|
// Клиент перестал наблюдать за сущностью
|
||||||
|
void prepareEntityRemove(ServerEntityId_t entityId);
|
||||||
|
|
||||||
// В зоне видимости добавилась новая сущность или она изменилась
|
// В зоне видимости добавилась новая сущность или она изменилась
|
||||||
void prepareEntityUpdate(ServerEntityId_t entityId, const Entity *entity);
|
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 prepareEntitySwap(ServerEntityId_t prevEntityId, ServerEntityId_t nextEntityId);
|
void prepareEntitySwap(ServerEntityId_t prevEntityId, ServerEntityId_t nextEntityId);
|
||||||
// Клиент перестал наблюдать за сущностью
|
|
||||||
void prepareEntityRemove(ServerEntityId_t entityId);
|
|
||||||
|
|
||||||
// В зоне видимости добавился порта или он изменился
|
// В зоне видимости добавился порта или он изменился
|
||||||
// void preparePortalUpdate(PortalId_t portalId, void* portal);
|
// void preparePortalUpdate(PortalId_t portalId, void* portal);
|
||||||
@@ -373,11 +416,11 @@ public:
|
|||||||
|
|
||||||
// Привязывает локальный идентификатор с хешем. Если его нет у клиента,
|
// Привязывает локальный идентификатор с хешем. Если его нет у клиента,
|
||||||
// то делается запрос на получение ресурсы для последующей отправки клиенту
|
// то делается запрос на получение ресурсы для последующей отправки клиенту
|
||||||
void informateIdToHash(const std::unordered_map<ResourceId_t, ResourceFile::Hash_t>* resourcesLink);
|
void informateIdToHash(const std::unordered_map<ResourceId, ResourceFile::Hash_t>* resourcesLink);
|
||||||
|
|
||||||
// Игровые определения
|
// Игровые определения
|
||||||
void informateDefVoxel(const std::unordered_map<DefVoxelId_t, DefVoxel_t*> &voxels);
|
void informateDefVoxel(const std::unordered_map<DefVoxelId, DefVoxel_t*> &voxels);
|
||||||
void informateDefNode(const std::unordered_map<DefNodeId_t, DefNode_t*> &nodes);
|
void informateDefNode(const std::unordered_map<DefNodeId, DefNode_t*> &nodes);
|
||||||
void informateDefWorld(const std::unordered_map<DefWorldId_t, DefWorld_t*> &worlds);
|
void informateDefWorld(const std::unordered_map<DefWorldId_t, DefWorld_t*> &worlds);
|
||||||
void informateDefPortal(const std::unordered_map<DefPortalId_t, DefPortal_t*> &portals);
|
void informateDefPortal(const std::unordered_map<DefPortalId_t, DefPortal_t*> &portals);
|
||||||
void informateDefEntity(const std::unordered_map<DefEntityId_t, DefEntity_t*> &entityes);
|
void informateDefEntity(const std::unordered_map<DefEntityId_t, DefEntity_t*> &entityes);
|
||||||
|
|||||||
Reference in New Issue
Block a user