]> git.localhorst.tv Git - blank.git/blobdiff - src/server/net.cpp
unified location handling
[blank.git] / src / server / net.cpp
index 38224ec9a57e879e2a84357a77456b30253f3f1c..9eac33ece573ed35edb24b78893b855f75c0feb3 100644 (file)
@@ -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<Packet::EntityUpdate>();
        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<Packet::Message>(serv_pack);
        pack.WriteType(type);