X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fserver%2Fnet.cpp;h=9eac33ece573ed35edb24b78893b855f75c0feb3;hb=4727825186798902f68df5b99a6a32f0ef618454;hp=38224ec9a57e879e2a84357a77456b30253f3f1c;hpb=150d065f431d665326fd8028748c48a74ad956bb;p=blank.git diff --git a/src/server/net.cpp b/src/server/net.cpp index 38224ec..9eac33e 100644 --- a/src/server/net.cpp +++ b/src/server/net.cpp @@ -3,6 +3,7 @@ #include "Server.hpp" #include "../app/init.hpp" +#include "../geometry/distance.hpp" #include "../io/WorldSave.hpp" #include "../model/Model.hpp" #include "../world/ChunkIndex.hpp" @@ -180,6 +181,7 @@ ClientConnection::ClientConnection(Server &server, const IPaddress &addr) , spawns() , confirm_wait(0) , entity_updates() +, entity_updates_skipped(0) , player_update_state() , player_update_pack(0) , player_update_timer(1500) @@ -211,7 +213,7 @@ void ClientConnection::Update(int dt) { // they're the same if (CanDespawn(*global_iter)) { SendDespawn(*local_iter); - } else { + } else if (SendingUpdates()) { // update QueueUpdate(*local_iter); } @@ -308,6 +310,10 @@ void ClientConnection::SendDespawn(SpawnStatus &status) { ++confirm_wait; } +bool ClientConnection::SendingUpdates() const noexcept { + return entity_updates_skipped >= NetStat().SuggestedPacketSkip(); +} + void ClientConnection::QueueUpdate(SpawnStatus &status) { // don't send updates while spawn not ack'd or despawn sent if (status.spawn_pack == -1 && status.despawn_pack == -1) { @@ -316,6 +322,11 @@ void ClientConnection::QueueUpdate(SpawnStatus &status) { } void ClientConnection::SendUpdates() { + if (!SendingUpdates()) { + entity_updates.clear(); + ++entity_updates_skipped; + return; + } auto base = PlayerChunks().Base(); auto pack = Prepare(); pack.WriteChunkBase(base); @@ -335,6 +346,7 @@ void ClientConnection::SendUpdates() { Send(Packet::EntityUpdate::GetSize(entity_pos)); } entity_updates.clear(); + entity_updates_skipped = 0; } void ClientConnection::CheckPlayerFix() { @@ -373,9 +385,9 @@ struct QueueCompare { void ClientConnection::CheckChunkQueue() { if (PlayerChunks().Base() != old_base) { - Chunk::Pos begin = PlayerChunks().CoordsBegin(); - Chunk::Pos end = PlayerChunks().CoordsEnd(); - for (Chunk::Pos pos = begin; pos.z < end.z; ++pos.z) { + ExactLocation::Coarse begin = PlayerChunks().CoordsBegin(); + ExactLocation::Coarse end = PlayerChunks().CoordsEnd(); + for (ExactLocation::Coarse pos = begin; pos.z < end.z; ++pos.z) { for (pos.y = begin.y; pos.y < end.y; ++pos.y) { for (pos.x = begin.x; pos.x < end.x; ++pos.x) { if (manhattan_radius(pos - old_base) > PlayerChunks().Extent()) { @@ -387,6 +399,11 @@ void ClientConnection::CheckChunkQueue() { old_base = PlayerChunks().Base(); sort(chunk_queue.begin(), chunk_queue.end(), QueueCompare(old_base)); } + // if we have packet skip enabled and just pushed an entity + // update, don't also send chunk data + if (NetStat().SuggestedPacketSkip() > 0 && entity_updates_skipped == 0) { + return; + } if (transmitter.Transmitting()) { transmitter.Transmit(); return; @@ -395,7 +412,7 @@ void ClientConnection::CheckChunkQueue() { int count = 0; constexpr int max = 64; while (count < max && !chunk_queue.empty()) { - Chunk::Pos pos = chunk_queue.front(); + ExactLocation::Coarse pos = chunk_queue.front(); chunk_queue.pop_front(); if (PlayerChunks().InRange(pos)) { Chunk *chunk = PlayerChunks().Get(pos); @@ -417,9 +434,9 @@ void ClientConnection::AttachPlayer(Player &player) { PlayerEntity().Ref(); old_base = PlayerChunks().Base(); - Chunk::Pos begin = PlayerChunks().CoordsBegin(); - Chunk::Pos end = PlayerChunks().CoordsEnd(); - for (Chunk::Pos pos = begin; pos.z < end.z; ++pos.z) { + ExactLocation::Coarse begin = PlayerChunks().CoordsBegin(); + ExactLocation::Coarse end = PlayerChunks().CoordsEnd(); + for (ExactLocation::Coarse pos = begin; pos.z < end.z; ++pos.z) { for (pos.y = begin.y; pos.y < end.y; ++pos.y) { for (pos.x = begin.x; pos.x < end.x; ++pos.x) { chunk_queue.push_back(pos); @@ -593,7 +610,7 @@ void ClientConnection::On(const Packet::Message &pack) { pack.ReadMessage(msg); if (type == 1 && HasPlayer()) { - server.DistributeMessage(1, PlayerEntity().ID(), msg); + server.DispatchMessage(input->GetPlayer(), msg); } } @@ -609,7 +626,8 @@ Server::Server( , world(world) , spawn_index(world.Chunks().MakeIndex(wc.spawn, 3)) , save(save) -, player_model(nullptr) { +, player_model(nullptr) +, cli(world) { serv_sock = SDLNet_UDP_Open(conf.port); if (!serv_sock) { throw NetError("SDLNet_UDP_Open"); @@ -724,6 +742,17 @@ void Server::SetBlock(Chunk &chunk, int index, const Block &block) { } } +void Server::DispatchMessage(Player &player, const string &msg) { + if (msg.empty()) { + return; + } + if (msg[0] == '/' && msg.size() > 1 && msg[1] != '/') { + cli.Execute(player, msg.substr(1)); + } else { + DistributeMessage(1, player.GetEntity().ID(), msg); + } +} + void Server::DistributeMessage(uint8_t type, uint32_t ref, const string &msg) { auto pack = Packet::Make(serv_pack); pack.WriteType(type);