-
This commit is contained in:
@@ -13,15 +13,15 @@ ContentEventController::ContentEventController(std::unique_ptr<RemoteClient> &&r
|
||||
}
|
||||
|
||||
uint8_t ContentEventController::getViewRange() const {
|
||||
return 3;
|
||||
return 16;
|
||||
}
|
||||
|
||||
ServerObjectPos ContentEventController::getLastPos() const {
|
||||
return {0, {0, 0, 0}};
|
||||
return {0, Remote->CameraPos};
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
@@ -408,6 +408,9 @@ void GameServer::stepPlayers() {
|
||||
|
||||
wIter->second->onCEC_RegionsLost(cec.get(), wPair.second);
|
||||
}
|
||||
|
||||
std::string username = cec->Remote->Username;
|
||||
External.ConnectedPlayersSet.lock_write()->erase(username);
|
||||
|
||||
cec.reset();
|
||||
}
|
||||
@@ -913,6 +916,7 @@ void GameServer::stepViewContent() {
|
||||
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.Range = cec.getViewRange();
|
||||
cvc.Range *= cvc.Range;
|
||||
|
||||
cec.ContentViewCircles = Expanse.calcAndRemapCVC(cvc);
|
||||
}
|
||||
@@ -926,34 +930,7 @@ void GameServer::stepViewContent() {
|
||||
ServerObjectPos oLPos = cec.getLastPos(), oPos = cec.getPos();
|
||||
|
||||
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;
|
||||
for(auto &pair : cec.ContentViewCircles) {
|
||||
@@ -992,6 +969,36 @@ void GameServer::stepViewContent() {
|
||||
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;
|
||||
|
||||
checkPacketBorder(voxels.size()*(2+6)+16);
|
||||
|
||||
NextPacket << (uint8_t) ToClient::L1::Content
|
||||
<< (uint8_t) ToClient::L2Content::ChunkVoxels << wcId
|
||||
<< 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;
|
||||
WorldId_c cwId = ResRemap.Worlds.toClient(worldId);
|
||||
WorldId_c cwId = worldId ? ResRemap.Worlds.toClient(worldId) : worldId;
|
||||
|
||||
checkPacketBorder(16);
|
||||
NextPacket << (uint8_t) ToClient::L1::Content
|
||||
<< (uint8_t) ToClient::L2Content::RemoveChunk
|
||||
<< cwId << Pos::GlobalChunk::Key(chunkPos);
|
||||
@@ -189,6 +193,8 @@ void RemoteClient::prepareWorldNew(WorldId_t worldId, World* world)
|
||||
|
||||
WorldId_c cId = ResRemap.Worlds.toClient(worldId);
|
||||
LOG.debug() << "Новый мир: " << worldId << " -> " << int(cId);
|
||||
|
||||
checkPacketBorder(16);
|
||||
NextPacket << (uint8_t) ToClient::L1::Content
|
||||
<< (uint8_t) ToClient::L2Content::World
|
||||
<< cId;
|
||||
@@ -231,7 +237,7 @@ void RemoteClient::prepareWorldUpdate(WorldId_t worldId, World* world)
|
||||
decrementBinary(lostTextures, lostSounds, lostModels);
|
||||
decrementBinary(newTextures, newSounds, newModels);
|
||||
|
||||
WorldId_c cId = ResRemap.Worlds.toClient(worldId);
|
||||
WorldId_c cId = worldId ? ResRemap.Worlds.toClient(worldId) : worldId;
|
||||
// TODO: отправить пакет об изменении мира
|
||||
LOG.debug() << "Изменение мира: " << worldId << " -> " << cId;
|
||||
}
|
||||
@@ -242,7 +248,7 @@ void RemoteClient::prepareWorldRemove(WorldId_t 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;
|
||||
|
||||
NextPacket << (uint8_t) ToClient::L1::Content
|
||||
@@ -323,6 +329,7 @@ void RemoteClient::prepareEntityRemove(GlobalEntityId_t entityId)
|
||||
|
||||
LOG.debug() << "Сущность потеряна: " << cId;
|
||||
|
||||
checkPacketBorder(16);
|
||||
NextPacket << (uint8_t) ToClient::L1::Content
|
||||
<< (uint8_t) ToClient::L2Content::RemoveEntity
|
||||
<< cId;
|
||||
@@ -357,6 +364,7 @@ void RemoteClient::informateDefTexture(const std::unordered_map<BinTextureId_t,
|
||||
|
||||
TextureId_c cId = ResRemap.BinTextures.toClient(sId);
|
||||
|
||||
checkPacketBorder(0);
|
||||
NextPacket << (uint8_t) ToClient::L1::Resource // Оповещение
|
||||
<< (uint8_t) ToClient::L2Resource::Texture << cId;
|
||||
for(auto part : pair.second->Hash)
|
||||
@@ -373,18 +381,12 @@ void RemoteClient::informateDefTexture(const std::unordered_map<BinTextureId_t,
|
||||
|
||||
size_t pos = 0;
|
||||
while(pos < pair.second->Data.size()) {
|
||||
if(NextPacket.size() > 64000) {
|
||||
SimplePackets.push_back(std::move(NextPacket));
|
||||
}
|
||||
|
||||
checkPacketBorder(0);
|
||||
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);
|
||||
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)
|
||||
@@ -396,6 +398,7 @@ void RemoteClient::informateDefSound(const std::unordered_map<BinSoundId_t, std:
|
||||
|
||||
SoundId_c cId = ResRemap.BinSounds.toClient(sId);
|
||||
|
||||
checkPacketBorder(0);
|
||||
NextPacket << (uint8_t) ToClient::L1::Resource // Оповещение
|
||||
<< (uint8_t) ToClient::L2Resource::Sound << cId;
|
||||
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() {
|
||||
shutdown(EnumDisconnect::ProtocolError, "Ошибка протокола");
|
||||
}
|
||||
@@ -569,6 +578,17 @@ coro<> RemoteClient::rP_System(Net::AsyncSocket &sock) {
|
||||
|
||||
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:
|
||||
protocolError();
|
||||
}
|
||||
|
||||
@@ -266,6 +266,8 @@ class RemoteClient {
|
||||
|
||||
public:
|
||||
const std::string Username;
|
||||
Pos::Object CameraPos = {0, 0, 0};
|
||||
ToServer::PacketQuat CameraQuat = {0};
|
||||
|
||||
public:
|
||||
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);
|
||||
|
||||
private:
|
||||
void checkPacketBorder(uint16_t size);
|
||||
void protocolError();
|
||||
coro<> readPacket(Net::AsyncSocket &sock);
|
||||
coro<> rP_System(Net::AsyncSocket &sock);
|
||||
|
||||
Reference in New Issue
Block a user