-
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,3 +12,4 @@
|
|||||||
/libassets.a
|
/libassets.a
|
||||||
/resources.cpp
|
/resources.cpp
|
||||||
/imgui.ini
|
/imgui.ini
|
||||||
|
/data
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
namespace LV::Client {
|
namespace LV::Client {
|
||||||
|
|
||||||
struct GlobalTime {
|
struct GlobalTime {
|
||||||
uint32_t Seconds : 22, Sub : 10;
|
uint32_t Seconds : 22 = 0, Sub : 10 = 0;
|
||||||
|
|
||||||
GlobalTime() = default;
|
GlobalTime() = default;
|
||||||
GlobalTime(double gTime) {
|
GlobalTime(double gTime) {
|
||||||
|
|||||||
@@ -28,6 +28,15 @@ struct PP_Content_ChunkVoxels : public ParsedPacket {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PP_Content_ChunkRemove : public ParsedPacket {
|
||||||
|
WorldId_c Id;
|
||||||
|
Pos::GlobalChunk Pos;
|
||||||
|
|
||||||
|
PP_Content_ChunkRemove(ToClient::L1 l1, uint8_t l2, WorldId_c id, Pos::GlobalChunk pos)
|
||||||
|
: ParsedPacket(l1, l2), Id(id), Pos(pos)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
using namespace TOS;
|
using namespace TOS;
|
||||||
|
|
||||||
ServerSession::~ServerSession() {
|
ServerSession::~ServerSession() {
|
||||||
@@ -246,14 +255,30 @@ void ServerSession::atFreeDrawTime(GlobalTime gTime, float dTime) {
|
|||||||
// Пакеты
|
// Пакеты
|
||||||
ParsedPacket *pack;
|
ParsedPacket *pack;
|
||||||
while(NetInputPackets.pop(pack)) {
|
while(NetInputPackets.pop(pack)) {
|
||||||
if(pack->Level1 == ToClient::L1::Content && ToClient::L2Content(pack->Level2) == ToClient::L2Content::ChunkVoxels) {
|
if(pack->Level1 == ToClient::L1::Content) {
|
||||||
|
ToClient::L2Content l2 = ToClient::L2Content(pack->Level2);
|
||||||
|
if(l2 == ToClient::L2Content::ChunkVoxels) {
|
||||||
PP_Content_ChunkVoxels &p = *dynamic_cast<PP_Content_ChunkVoxels*>(pack);
|
PP_Content_ChunkVoxels &p = *dynamic_cast<PP_Content_ChunkVoxels*>(pack);
|
||||||
Pos::GlobalRegion rPos(p.Pos.X >> 4, p.Pos.Y >> 4, p.Pos.Z >> 4);
|
Pos::GlobalRegion rPos(p.Pos.X >> 4, p.Pos.Y >> 4, p.Pos.Z >> 4);
|
||||||
Pos::Local16_u cPos(p.Pos.X & 0xf, p.Pos.Y & 0xf, p.Pos.Z & 0xf);
|
Pos::Local16_u cPos(p.Pos.X & 0xf, p.Pos.Y & 0xf, p.Pos.Z & 0xf);
|
||||||
|
|
||||||
External.Worlds[p.Id].Regions[rPos].Chunks[cPos].Voxels = std::move(p.Cubes);
|
External.Worlds[p.Id].Regions[rPos].Chunks[cPos].Voxels = std::move(p.Cubes);
|
||||||
|
|
||||||
auto &pair = changeOrAddList_removeList[p.Id];
|
auto &pair = changeOrAddList_removeList[p.Id];
|
||||||
std::get<0>(pair).insert(p.Pos);
|
std::get<0>(pair).insert(p.Pos);
|
||||||
|
} else if(l2 == ToClient::L2Content::RemoveChunk) {
|
||||||
|
PP_Content_ChunkRemove &p = *dynamic_cast<PP_Content_ChunkRemove*>(pack);
|
||||||
|
|
||||||
|
Pos::GlobalRegion rPos(p.Pos.X >> 4, p.Pos.Y >> 4, p.Pos.Z >> 4);
|
||||||
|
Pos::Local16_u cPos(p.Pos.X & 0xf, p.Pos.Y & 0xf, p.Pos.Z & 0xf);
|
||||||
|
auto &obj = External.Worlds[p.Id].Regions[rPos].Chunks;
|
||||||
|
auto iter = obj.find(cPos);
|
||||||
|
if(iter != obj.end())
|
||||||
|
obj.erase(iter);
|
||||||
|
|
||||||
|
auto &pair = changeOrAddList_removeList[p.Id];
|
||||||
|
std::get<1>(pair).insert(p.Pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete pack;
|
delete pack;
|
||||||
@@ -261,14 +286,15 @@ void ServerSession::atFreeDrawTime(GlobalTime gTime, float dTime) {
|
|||||||
|
|
||||||
if(RS && !changeOrAddList_removeList.empty()) {
|
if(RS && !changeOrAddList_removeList.empty()) {
|
||||||
for(auto &pair : changeOrAddList_removeList) {
|
for(auto &pair : changeOrAddList_removeList) {
|
||||||
|
// Если случится что чанк был изменён и удалён, то исключаем его обновления
|
||||||
|
for(Pos::GlobalChunk removed : std::get<1>(pair.second))
|
||||||
|
std::get<0>(pair.second).erase(removed);
|
||||||
|
|
||||||
RS->onChunksChange(pair.first, std::get<0>(pair.second), std::get<1>(pair.second));
|
RS->onChunksChange(pair.first, std::get<0>(pair.second), std::get<1>(pair.second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!RS)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Расчёт камеры
|
// Расчёт камеры
|
||||||
{
|
{
|
||||||
float deltaTime = 1-std::min<float>(gTime-PYR_At, 1/PYR_TIME_DELTA)*PYR_TIME_DELTA;
|
float deltaTime = 1-std::min<float>(gTime-PYR_At, 1/PYR_TIME_DELTA)*PYR_TIME_DELTA;
|
||||||
@@ -277,7 +303,27 @@ void ServerSession::atFreeDrawTime(GlobalTime gTime, float dTime) {
|
|||||||
glm::angleAxis(PYR.x-deltaTime*PYR_Offset.x, glm::vec3(1.f, 0.f, 0.f))
|
glm::angleAxis(PYR.x-deltaTime*PYR_Offset.x, glm::vec3(1.f, 0.f, 0.f))
|
||||||
* glm::angleAxis(PYR.y-deltaTime*PYR_Offset.y, glm::vec3(0.f, -1.f, 0.f));
|
* glm::angleAxis(PYR.y-deltaTime*PYR_Offset.y, glm::vec3(0.f, -1.f, 0.f));
|
||||||
|
|
||||||
|
if(RS)
|
||||||
RS->setCameraPos(0, Pos, quat);
|
RS->setCameraPos(0, Pos, quat);
|
||||||
|
|
||||||
|
|
||||||
|
// Отправка текущей позиции камеры
|
||||||
|
if(gTime-LastSendPYR_POS > 1/20.f)
|
||||||
|
{
|
||||||
|
LastSendPYR_POS = gTime;
|
||||||
|
Net::Packet packet;
|
||||||
|
ToServer::PacketQuat q;
|
||||||
|
q.fromQuat(quat);
|
||||||
|
|
||||||
|
packet << (uint8_t) ToServer::L1::System
|
||||||
|
<< (uint8_t) ToServer::L2System::Test_CAM_PYR_POS
|
||||||
|
<< Pos.x << Pos.y << Pos.z;
|
||||||
|
|
||||||
|
for(int iter = 0; iter < 5; iter++)
|
||||||
|
packet << q.Data[iter];
|
||||||
|
|
||||||
|
Socket->pushPacket(std::move(packet));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,9 +538,22 @@ coro<> ServerSession::rP_Content(Net::AsyncSocket &sock) {
|
|||||||
case ToClient::L2Content::ChunkLightPrism:
|
case ToClient::L2Content::ChunkLightPrism:
|
||||||
|
|
||||||
co_return;
|
co_return;
|
||||||
case ToClient::L2Content::RemoveChunk:
|
case ToClient::L2Content::RemoveChunk: {
|
||||||
|
WorldId_c wcId = co_await sock.read<uint8_t>();
|
||||||
|
Pos::GlobalChunk::Key posKey = co_await sock.read<Pos::GlobalChunk::Key>();
|
||||||
|
Pos::GlobalChunk pos = *(Pos::GlobalChunk*) &posKey;
|
||||||
|
|
||||||
|
PP_Content_ChunkRemove *packet = new PP_Content_ChunkRemove(
|
||||||
|
ToClient::L1::Content,
|
||||||
|
(uint8_t) ToClient::L2Content::RemoveChunk,
|
||||||
|
wcId,
|
||||||
|
pos
|
||||||
|
);
|
||||||
|
|
||||||
|
while(!NetInputPackets.push(packet));
|
||||||
|
|
||||||
co_return;
|
co_return;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
protocolError();
|
protocolError();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ class ServerSession : public AsyncObject, public IServerSession, public ISurface
|
|||||||
} Keys;
|
} Keys;
|
||||||
Pos::Object Pos = Pos::Object(0), Speed = Pos::Object(0);
|
Pos::Object Pos = Pos::Object(0), Speed = Pos::Object(0);
|
||||||
|
|
||||||
|
GlobalTime LastSendPYR_POS;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Нужен сокет, на котором только что был согласован игровой протокол (asyncInitGameProtocol)
|
// Нужен сокет, на котором только что был согласован игровой протокол (asyncInitGameProtocol)
|
||||||
ServerSession(asio::io_context &ioc, std::unique_ptr<Net::AsyncSocket> &&socket, IRenderSession *rs = nullptr)
|
ServerSession(asio::io_context &ioc, std::unique_ptr<Net::AsyncSocket> &&socket, IRenderSession *rs = nullptr)
|
||||||
|
|||||||
@@ -2129,6 +2129,10 @@ void Vulkan::gui_ConnectedToServer() {
|
|||||||
Game.RSession = nullptr;
|
Game.RSession = nullptr;
|
||||||
Game.Session = nullptr;
|
Game.Session = nullptr;
|
||||||
Game.ImGuiInterfaces.pop_back();
|
Game.ImGuiInterfaces.pop_back();
|
||||||
|
|
||||||
|
int mode = glfwGetInputMode(Graphics.Window, GLFW_CURSOR);
|
||||||
|
if(mode == GLFW_CURSOR_DISABLED)
|
||||||
|
glfwSetInputMode(Graphics.Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
#include "Client/Vulkan/Vulkan.hpp"
|
#include "Client/Vulkan/Vulkan.hpp"
|
||||||
#include "Common/Abstract.hpp"
|
#include "Common/Abstract.hpp"
|
||||||
#include "assets.hpp"
|
#include "assets.hpp"
|
||||||
|
#include "glm/ext/matrix_transform.hpp"
|
||||||
#include "glm/trigonometric.hpp"
|
#include "glm/trigonometric.hpp"
|
||||||
|
#include <cstddef>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan_core.h>
|
||||||
@@ -630,31 +632,41 @@ void VulkanRenderSession::onDefEntityUpdates(const std::vector<DefEntityId_c> &u
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderSession::onChunksChange(WorldId_c worldId, const std::unordered_set<Pos::GlobalChunk> &changeOrAddList, const std::unordered_set<Pos::GlobalChunk> &remove) {
|
void VulkanRenderSession::onChunksChange(WorldId_c worldId, const std::unordered_set<Pos::GlobalChunk> &changeOrAddList, const std::unordered_set<Pos::GlobalChunk> &remove) {
|
||||||
|
auto &table = External.ChunkVoxelMesh[worldId];
|
||||||
|
|
||||||
for(Pos::GlobalChunk pos : changeOrAddList) {
|
for(Pos::GlobalChunk pos : changeOrAddList) {
|
||||||
Pos::GlobalRegion rPos(pos.X >> 4, pos.Y >> 4, pos.Z >> 4);
|
Pos::GlobalRegion rPos(pos.X >> 4, pos.Y >> 4, pos.Z >> 4);
|
||||||
Pos::Local16_u cPos(pos.X & 0xf, pos.Y & 0xf, pos.Z & 0xf);
|
Pos::Local16_u cPos(pos.X & 0xf, pos.Y & 0xf, pos.Z & 0xf);
|
||||||
|
|
||||||
const auto &voxels = ServerSession->External.Worlds[worldId].Regions[rPos].Chunks[cPos].Voxels;
|
const auto &voxels = ServerSession->External.Worlds[worldId].Regions[rPos].Chunks[cPos].Voxels;
|
||||||
auto &table = External.ChunkVoxelMesh[worldId];
|
|
||||||
|
|
||||||
if(voxels.empty()) {
|
if(voxels.empty()) {
|
||||||
auto iter = table.find(pos);
|
auto iter = table.find(pos);
|
||||||
if(iter != table.end())
|
if(iter != table.end())
|
||||||
table.erase(iter);
|
table.erase(iter);
|
||||||
|
} else {
|
||||||
|
std::vector<VoxelVertexPoint> vertexs = generateMeshForVoxelChunks(voxels);
|
||||||
|
|
||||||
|
if(!vertexs.empty()) {
|
||||||
|
auto &buffer = table[pos] = std::make_unique<Buffer>(VkInst, vertexs.size()*sizeof(VoxelVertexPoint));
|
||||||
|
std::copy(vertexs.data(), vertexs.data()+vertexs.size(), (VoxelVertexPoint*) buffer->mapMemory());
|
||||||
|
buffer->unMapMemory();
|
||||||
|
} else {
|
||||||
|
auto iter = table.find(pos);
|
||||||
|
if(iter != table.end())
|
||||||
|
table.erase(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Pos::GlobalChunk pos : remove) {
|
||||||
|
auto iter = table.find(pos);
|
||||||
|
if(iter != table.end())
|
||||||
|
table.erase(iter);
|
||||||
|
}
|
||||||
|
|
||||||
if(table.empty())
|
if(table.empty())
|
||||||
External.ChunkVoxelMesh.erase(External.ChunkVoxelMesh.find(worldId));
|
External.ChunkVoxelMesh.erase( External.ChunkVoxelMesh.find(worldId));
|
||||||
} else {
|
|
||||||
auto &buffer = table[pos] = std::make_unique<Buffer>(VkInst, voxels.size()*6*6*sizeof(NodeVertexStatic));
|
|
||||||
NodeVertexStatic *vertex = (NodeVertexStatic*) buffer->mapMemory();
|
|
||||||
|
|
||||||
for(const VoxelCube &cube : voxels) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer->unMapMemory();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderSession::setCameraPos(WorldId_c worldId, Pos::Object pos, glm::quat quat) {
|
void VulkanRenderSession::setCameraPos(WorldId_c worldId, Pos::Object pos, glm::quat quat) {
|
||||||
@@ -719,6 +731,26 @@ void VulkanRenderSession::drawWorld(GlobalTime gTime, float dTime, VkCommandBuff
|
|||||||
vkCmdBindVertexBuffers(drawCmd, 0, 1, &vkBuffer, &vkOffsets);
|
vkCmdBindVertexBuffers(drawCmd, 0, 1, &vkBuffer, &vkOffsets);
|
||||||
vkCmdDraw(drawCmd, VKCTX->TestVoxel->getSize() / sizeof(VoxelVertexPoint), 1, 0, 0);
|
vkCmdDraw(drawCmd, VKCTX->TestVoxel->getSize() / sizeof(VoxelVertexPoint), 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto iterWorld = External.ChunkVoxelMesh.find(WorldId);
|
||||||
|
if(iterWorld != External.ChunkVoxelMesh.end()) {
|
||||||
|
glm::mat4 orig = PCO.Model;
|
||||||
|
|
||||||
|
for(auto &pair : iterWorld->second) {
|
||||||
|
glm::vec3 cpos(pair.first.X, pair.first.Y, pair.first.Z);
|
||||||
|
PCO.Model = glm::translate(orig, cpos*16.f);
|
||||||
|
vkBuffer = *pair.second;
|
||||||
|
|
||||||
|
vkCmdPushConstants(drawCmd, MainAtlas_LightMap_PipelineLayout,
|
||||||
|
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT, offsetof(WorldPCO, Model), sizeof(WorldPCO::Model), &PCO.Model);
|
||||||
|
vkCmdBindVertexBuffers(drawCmd, 0, 1, &vkBuffer, &vkOffsets);
|
||||||
|
vkCmdDraw(drawCmd, pair.second->getSize() / sizeof(VoxelVertexPoint), 1, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
PCO.Model = orig;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VoxelVertexPoint> VulkanRenderSession::generateMeshForVoxelChunks(const std::vector<VoxelCube> cubes) {
|
std::vector<VoxelVertexPoint> VulkanRenderSession::generateMeshForVoxelChunks(const std::vector<VoxelCube> cubes) {
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ enum struct L1 : uint8_t {
|
|||||||
// Второй уровень
|
// Второй уровень
|
||||||
enum struct L2System : uint8_t {
|
enum struct L2System : uint8_t {
|
||||||
InitEnd,
|
InitEnd,
|
||||||
Disconnect
|
Disconnect,
|
||||||
|
Test_CAM_PYR_POS
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,15 +13,15 @@ ContentEventController::ContentEventController(std::unique_ptr<RemoteClient> &&r
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t ContentEventController::getViewRange() const {
|
uint8_t ContentEventController::getViewRange() const {
|
||||||
return 3;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerObjectPos ContentEventController::getLastPos() const {
|
ServerObjectPos ContentEventController::getLastPos() const {
|
||||||
return {0, {0, 0, 0}};
|
return {0, Remote->CameraPos};
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerObjectPos ContentEventController::getPos() const {
|
ServerObjectPos ContentEventController::getPos() const {
|
||||||
return {0, {0, 0, 0}};
|
return {0, Remote->CameraPos};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentEventController::onRegionsLost(WorldId_t worldId, const std::vector<Pos::GlobalRegion> &lost) {
|
void ContentEventController::onRegionsLost(WorldId_t worldId, const std::vector<Pos::GlobalRegion> &lost) {
|
||||||
|
|||||||
@@ -409,6 +409,9 @@ void GameServer::stepPlayers() {
|
|||||||
wIter->second->onCEC_RegionsLost(cec.get(), wPair.second);
|
wIter->second->onCEC_RegionsLost(cec.get(), wPair.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string username = cec->Remote->Username;
|
||||||
|
External.ConnectedPlayersSet.lock_write()->erase(username);
|
||||||
|
|
||||||
cec.reset();
|
cec.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -913,6 +916,7 @@ void GameServer::stepViewContent() {
|
|||||||
cvc.WorldId = oPos.WorldId;
|
cvc.WorldId = oPos.WorldId;
|
||||||
cvc.Pos = {oPos.ObjectPos.x >> (Pos::Object_t::BS_Bit+4), oPos.ObjectPos.y >> (Pos::Object_t::BS_Bit+4), oPos.ObjectPos.z >> (Pos::Object_t::BS_Bit+4)};
|
cvc.Pos = {oPos.ObjectPos.x >> (Pos::Object_t::BS_Bit+4), oPos.ObjectPos.y >> (Pos::Object_t::BS_Bit+4), oPos.ObjectPos.z >> (Pos::Object_t::BS_Bit+4)};
|
||||||
cvc.Range = cec.getViewRange();
|
cvc.Range = cec.getViewRange();
|
||||||
|
cvc.Range *= cvc.Range;
|
||||||
|
|
||||||
cec.ContentViewCircles = Expanse.calcAndRemapCVC(cvc);
|
cec.ContentViewCircles = Expanse.calcAndRemapCVC(cvc);
|
||||||
}
|
}
|
||||||
@@ -927,33 +931,6 @@ void GameServer::stepViewContent() {
|
|||||||
|
|
||||||
std::vector<Pos::GlobalRegion> lost;
|
std::vector<Pos::GlobalRegion> lost;
|
||||||
|
|
||||||
// Снимаем подписки с регионов
|
|
||||||
for(auto &pairSR : cec.SubscribedRegions) {
|
|
||||||
auto CVCs = cec.ContentViewCircles.find(pairSR.first);
|
|
||||||
|
|
||||||
if(CVCs == cec.ContentViewCircles.end()) {
|
|
||||||
lost = pairSR.second;
|
|
||||||
} else {
|
|
||||||
for(Pos::GlobalRegion ®ion : pairSR.second) {
|
|
||||||
for(ContentViewCircle &circle : CVCs->second) {
|
|
||||||
if(!circle.isIn(region)) {
|
|
||||||
lost.push_back(region);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cec.onRegionsLost(pairSR.first, lost);
|
|
||||||
|
|
||||||
auto world = Expanse.Worlds.find(pairSR.first);
|
|
||||||
if(world != Expanse.Worlds.end())
|
|
||||||
world->second->onCEC_RegionsLost(&cec, lost);
|
|
||||||
|
|
||||||
lost.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Проверяем отслеживаемые регионы
|
// Проверяем отслеживаемые регионы
|
||||||
std::vector<Pos::GlobalRegion> regionsResult;
|
std::vector<Pos::GlobalRegion> regionsResult;
|
||||||
for(auto &pair : cec.ContentViewCircles) {
|
for(auto &pair : cec.ContentViewCircles) {
|
||||||
@@ -992,6 +969,36 @@ void GameServer::stepViewContent() {
|
|||||||
regionsResult.clear();
|
regionsResult.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Снимаем подписки с регионов
|
||||||
|
for(auto &pairSR : cec.SubscribedRegions) {
|
||||||
|
auto CVCs = cec.ContentViewCircles.find(pairSR.first);
|
||||||
|
|
||||||
|
if(CVCs == cec.ContentViewCircles.end()) {
|
||||||
|
lost = pairSR.second;
|
||||||
|
} else {
|
||||||
|
for(Pos::GlobalRegion ®ion : pairSR.second) {
|
||||||
|
bool inView = false;
|
||||||
|
for(ContentViewCircle &circle : CVCs->second) {
|
||||||
|
if(circle.isIn(region)) {
|
||||||
|
inView = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!inView)
|
||||||
|
lost.push_back(region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cec.onRegionsLost(pairSR.first, lost);
|
||||||
|
|
||||||
|
auto world = Expanse.Worlds.find(pairSR.first);
|
||||||
|
if(world != Expanse.Worlds.end())
|
||||||
|
world->second->onCEC_RegionsLost(&cec, lost);
|
||||||
|
|
||||||
|
lost.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,8 @@ void RemoteClient::prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::GlobalChunk
|
|||||||
|
|
||||||
LOG.debug() << "Воксели чанка: " << worldId << " / " << chunkPos.X << ":" << chunkPos.Y << ":" << chunkPos.Z;
|
LOG.debug() << "Воксели чанка: " << worldId << " / " << chunkPos.X << ":" << chunkPos.Y << ":" << chunkPos.Z;
|
||||||
|
|
||||||
|
checkPacketBorder(voxels.size()*(2+6)+16);
|
||||||
|
|
||||||
NextPacket << (uint8_t) ToClient::L1::Content
|
NextPacket << (uint8_t) ToClient::L1::Content
|
||||||
<< (uint8_t) ToClient::L2Content::ChunkVoxels << wcId
|
<< (uint8_t) ToClient::L2Content::ChunkVoxels << wcId
|
||||||
<< Pos::GlobalChunk::Key(chunkPos);
|
<< Pos::GlobalChunk::Key(chunkPos);
|
||||||
@@ -164,7 +166,9 @@ void RemoteClient::prepareChunkRemove(WorldId_t worldId, Pos::GlobalChunk chunkP
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOG.debug() << "Чанк потерян: " << worldId << " / " << chunkPos.X << ":" << chunkPos.Y << ":" << chunkPos.Z;
|
LOG.debug() << "Чанк потерян: " << worldId << " / " << chunkPos.X << ":" << chunkPos.Y << ":" << chunkPos.Z;
|
||||||
WorldId_c cwId = ResRemap.Worlds.toClient(worldId);
|
WorldId_c cwId = worldId ? ResRemap.Worlds.toClient(worldId) : worldId;
|
||||||
|
|
||||||
|
checkPacketBorder(16);
|
||||||
NextPacket << (uint8_t) ToClient::L1::Content
|
NextPacket << (uint8_t) ToClient::L1::Content
|
||||||
<< (uint8_t) ToClient::L2Content::RemoveChunk
|
<< (uint8_t) ToClient::L2Content::RemoveChunk
|
||||||
<< cwId << Pos::GlobalChunk::Key(chunkPos);
|
<< cwId << Pos::GlobalChunk::Key(chunkPos);
|
||||||
@@ -189,6 +193,8 @@ void RemoteClient::prepareWorldNew(WorldId_t worldId, World* world)
|
|||||||
|
|
||||||
WorldId_c cId = ResRemap.Worlds.toClient(worldId);
|
WorldId_c cId = ResRemap.Worlds.toClient(worldId);
|
||||||
LOG.debug() << "Новый мир: " << worldId << " -> " << int(cId);
|
LOG.debug() << "Новый мир: " << worldId << " -> " << int(cId);
|
||||||
|
|
||||||
|
checkPacketBorder(16);
|
||||||
NextPacket << (uint8_t) ToClient::L1::Content
|
NextPacket << (uint8_t) ToClient::L1::Content
|
||||||
<< (uint8_t) ToClient::L2Content::World
|
<< (uint8_t) ToClient::L2Content::World
|
||||||
<< cId;
|
<< cId;
|
||||||
@@ -231,7 +237,7 @@ void RemoteClient::prepareWorldUpdate(WorldId_t worldId, World* world)
|
|||||||
decrementBinary(lostTextures, lostSounds, lostModels);
|
decrementBinary(lostTextures, lostSounds, lostModels);
|
||||||
decrementBinary(newTextures, newSounds, newModels);
|
decrementBinary(newTextures, newSounds, newModels);
|
||||||
|
|
||||||
WorldId_c cId = ResRemap.Worlds.toClient(worldId);
|
WorldId_c cId = worldId ? ResRemap.Worlds.toClient(worldId) : worldId;
|
||||||
// TODO: отправить пакет об изменении мира
|
// TODO: отправить пакет об изменении мира
|
||||||
LOG.debug() << "Изменение мира: " << worldId << " -> " << cId;
|
LOG.debug() << "Изменение мира: " << worldId << " -> " << cId;
|
||||||
}
|
}
|
||||||
@@ -242,7 +248,7 @@ void RemoteClient::prepareWorldRemove(WorldId_t worldId)
|
|||||||
// Понизим зависимости ресурсов
|
// Понизим зависимости ресурсов
|
||||||
ResUsesObj::WorldResourceUse &res = ResUses.Worlds[worldId];
|
ResUsesObj::WorldResourceUse &res = ResUses.Worlds[worldId];
|
||||||
|
|
||||||
WorldId_c cWorld = ResUses.Worlds.erase(worldId);
|
WorldId_c cWorld = worldId ? ResUses.Worlds.erase(worldId) : worldId;
|
||||||
LOG.debug() << "Мир потерян: " << worldId << " -> " << cWorld;
|
LOG.debug() << "Мир потерян: " << worldId << " -> " << cWorld;
|
||||||
|
|
||||||
NextPacket << (uint8_t) ToClient::L1::Content
|
NextPacket << (uint8_t) ToClient::L1::Content
|
||||||
@@ -323,6 +329,7 @@ void RemoteClient::prepareEntityRemove(GlobalEntityId_t entityId)
|
|||||||
|
|
||||||
LOG.debug() << "Сущность потеряна: " << cId;
|
LOG.debug() << "Сущность потеряна: " << cId;
|
||||||
|
|
||||||
|
checkPacketBorder(16);
|
||||||
NextPacket << (uint8_t) ToClient::L1::Content
|
NextPacket << (uint8_t) ToClient::L1::Content
|
||||||
<< (uint8_t) ToClient::L2Content::RemoveEntity
|
<< (uint8_t) ToClient::L2Content::RemoveEntity
|
||||||
<< cId;
|
<< cId;
|
||||||
@@ -357,6 +364,7 @@ void RemoteClient::informateDefTexture(const std::unordered_map<BinTextureId_t,
|
|||||||
|
|
||||||
TextureId_c cId = ResRemap.BinTextures.toClient(sId);
|
TextureId_c cId = ResRemap.BinTextures.toClient(sId);
|
||||||
|
|
||||||
|
checkPacketBorder(0);
|
||||||
NextPacket << (uint8_t) ToClient::L1::Resource // Оповещение
|
NextPacket << (uint8_t) ToClient::L1::Resource // Оповещение
|
||||||
<< (uint8_t) ToClient::L2Resource::Texture << cId;
|
<< (uint8_t) ToClient::L2Resource::Texture << cId;
|
||||||
for(auto part : pair.second->Hash)
|
for(auto part : pair.second->Hash)
|
||||||
@@ -373,18 +381,12 @@ void RemoteClient::informateDefTexture(const std::unordered_map<BinTextureId_t,
|
|||||||
|
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
while(pos < pair.second->Data.size()) {
|
while(pos < pair.second->Data.size()) {
|
||||||
if(NextPacket.size() > 64000) {
|
checkPacketBorder(0);
|
||||||
SimplePackets.push_back(std::move(NextPacket));
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t need = std::min(pair.second->Data.size()-pos, std::min<size_t>(NextPacket.size(), 64000));
|
size_t need = std::min(pair.second->Data.size()-pos, std::min<size_t>(NextPacket.size(), 64000));
|
||||||
NextPacket.write(pair.second->Data.data()+pos, need);
|
NextPacket.write(pair.second->Data.data()+pos, need);
|
||||||
pos += need;
|
pos += need;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(NextPacket.size())
|
|
||||||
SimplePackets.push_back(std::move(NextPacket));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteClient::informateDefSound(const std::unordered_map<BinSoundId_t, std::shared_ptr<ResourceFile>> &sounds)
|
void RemoteClient::informateDefSound(const std::unordered_map<BinSoundId_t, std::shared_ptr<ResourceFile>> &sounds)
|
||||||
@@ -396,6 +398,7 @@ void RemoteClient::informateDefSound(const std::unordered_map<BinSoundId_t, std:
|
|||||||
|
|
||||||
SoundId_c cId = ResRemap.BinSounds.toClient(sId);
|
SoundId_c cId = ResRemap.BinSounds.toClient(sId);
|
||||||
|
|
||||||
|
checkPacketBorder(0);
|
||||||
NextPacket << (uint8_t) ToClient::L1::Resource // Оповещение
|
NextPacket << (uint8_t) ToClient::L1::Resource // Оповещение
|
||||||
<< (uint8_t) ToClient::L2Resource::Sound << cId;
|
<< (uint8_t) ToClient::L2Resource::Sound << cId;
|
||||||
for(auto part : pair.second->Hash)
|
for(auto part : pair.second->Hash)
|
||||||
@@ -534,6 +537,12 @@ void RemoteClient::informateDefPortals(const std::unordered_map<DefPortalId_t, v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemoteClient::checkPacketBorder(uint16_t size) {
|
||||||
|
if(64000-NextPacket.size() < size || (NextPacket.size() != 0 && size == 0)) {
|
||||||
|
SimplePackets.push_back(std::move(NextPacket));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RemoteClient::protocolError() {
|
void RemoteClient::protocolError() {
|
||||||
shutdown(EnumDisconnect::ProtocolError, "Ошибка протокола");
|
shutdown(EnumDisconnect::ProtocolError, "Ошибка протокола");
|
||||||
}
|
}
|
||||||
@@ -569,6 +578,17 @@ coro<> RemoteClient::rP_System(Net::AsyncSocket &sock) {
|
|||||||
|
|
||||||
co_return;
|
co_return;
|
||||||
}
|
}
|
||||||
|
case ToServer::L2System::Test_CAM_PYR_POS:
|
||||||
|
{
|
||||||
|
CameraPos.x = co_await sock.read<decltype(CameraPos.x)>();
|
||||||
|
CameraPos.y = co_await sock.read<decltype(CameraPos.x)>();
|
||||||
|
CameraPos.z = co_await sock.read<decltype(CameraPos.x)>();
|
||||||
|
|
||||||
|
for(int iter = 0; iter < 5; iter++)
|
||||||
|
CameraQuat.Data[iter] = co_await sock.read<uint8_t>();
|
||||||
|
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
protocolError();
|
protocolError();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -266,6 +266,8 @@ class RemoteClient {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
const std::string Username;
|
const std::string Username;
|
||||||
|
Pos::Object CameraPos = {0, 0, 0};
|
||||||
|
ToServer::PacketQuat CameraQuat = {0};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RemoteClient(asio::io_context &ioc, tcp::socket socket, const std::string username)
|
RemoteClient(asio::io_context &ioc, tcp::socket socket, const std::string username)
|
||||||
@@ -331,6 +333,7 @@ public:
|
|||||||
void informateDefPortals(const std::unordered_map<DefPortalId_t, void*> &portals);
|
void informateDefPortals(const std::unordered_map<DefPortalId_t, void*> &portals);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void checkPacketBorder(uint16_t size);
|
||||||
void protocolError();
|
void protocolError();
|
||||||
coro<> readPacket(Net::AsyncSocket &sock);
|
coro<> readPacket(Net::AsyncSocket &sock);
|
||||||
coro<> rP_System(Net::AsyncSocket &sock);
|
coro<> rP_System(Net::AsyncSocket &sock);
|
||||||
|
|||||||
Reference in New Issue
Block a user