]> git.localhorst.tv Git - blank.git/commitdiff
send updates less frequently on bad connections
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Tue, 27 Oct 2015 16:15:42 +0000 (17:15 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Tue, 27 Oct 2015 16:25:47 +0000 (17:25 +0100)
src/client/InteractiveState.hpp
src/client/NetworkedInput.hpp
src/client/client.cpp
src/client/net.cpp
src/net/CongestionControl.hpp
src/server/ClientConnection.hpp
src/server/net.cpp

index 7368e420829b7e9e49f4af062bf72be5d4607421..ac8f87b054bf4bf98fc382b5924f1ec57a33b8f8 100644 (file)
@@ -101,6 +101,9 @@ private:
 
        ChatState chat;
 
+       int time_skipped;
+       unsigned int packets_skipped;
+
 };
 
 }
index b557b1b0b3eb289f92aa8e152d8398ea68ca5644..3a61d90910e785ec67ce7628ca8e1b1faabf7e8e 100644 (file)
@@ -20,6 +20,7 @@ class NetworkedInput
 public:
        explicit NetworkedInput(World &, Player &, Client &);
 
+       bool UpdateImportant() const noexcept;
        void Update(Entity &, float dt) override;
        void PushPlayerUpdate(int dt);
        void MergePlayerCorrection(std::uint16_t, const EntityState &);
@@ -44,6 +45,9 @@ private:
        };
        std::list<PlayerHistory> player_hist;
 
+       glm::vec3 old_movement;
+
+       std::uint8_t old_actions;
        std::uint8_t actions;
 
 };
index 0eec9847b0473e666197052dd6b3f668d40411ef..d20a98c32bcdcd514d44fb7ef37c5964416f9fb0 100644 (file)
@@ -62,7 +62,9 @@ InteractiveState::InteractiveState(MasterState &master, uint32_t player_id)
 , stat_timer(1000)
 , sky(master.GetEnv().loader.LoadCubeMap("skybox"))
 , update_status()
-, chat(master.GetEnv(), *this, *this) {
+, chat(master.GetEnv(), *this, *this)
+, time_skipped(0)
+, packets_skipped(0) {
        if (!save.Exists()) {
                save.Write(master.GetWorldConf());
        }
@@ -163,7 +165,14 @@ void InteractiveState::Update(int dt) {
                hud.FocusNone();
        }
        if (world_dt > 0) {
-               input.PushPlayerUpdate(world_dt);
+               if (input.UpdateImportant() || packets_skipped >= master.NetStat().SuggestedPacketSkip()) {
+                       input.PushPlayerUpdate(time_skipped + world_dt);
+                       time_skipped = 0;
+                       packets_skipped = 0;
+               } else {
+                       time_skipped += world_dt;
+                       ++packets_skipped;
+               }
        }
        hud.Display(res.block_types[player.GetInventorySlot() + 1]);
        if (stat_timer.Hit()) {
index 6677f5143d3647d9bd3bc7e24ad1a6ec4beca9b3..18f593ac5831d218f0019723c511ff977a7e2ffe 100644 (file)
@@ -321,10 +321,16 @@ NetworkedInput::NetworkedInput(World &world, Player &player, Client &client)
 : PlayerController(world, player)
 , client(client)
 , player_hist()
+, old_movement(0.0f)
+, old_actions(0)
 , actions(0) {
 
 }
 
+bool NetworkedInput::UpdateImportant() const noexcept {
+       return old_actions != actions || !iszero(old_movement - GetMovement());
+}
+
 void NetworkedInput::Update(Entity &, float dt) {
        Invalidate();
        UpdatePlayer();
@@ -351,6 +357,8 @@ void NetworkedInput::PushPlayerUpdate(int dt) {
                entry->packet = packet;
                player_hist.splice(player_hist.end(), player_hist, entry);
        }
+       old_movement = GetMovement();
+       old_actions = actions;
 }
 
 void NetworkedInput::MergePlayerCorrection(uint16_t seq, const EntityState &corrected_state) {
index ea71c55abe7c8625a42c31edf48f0fe8e01b2e45..7d4bacacb39a55d1e34dd5aae73367f0af678c06 100644 (file)
@@ -21,6 +21,8 @@ public:
 
        /// get recommended mode of operation
        Mode GetMode() const noexcept { return mode; }
+       /// according to current mode, drop this many unimportant packets
+       unsigned int SuggestedPacketSkip() const noexcept { return (1 << mode) - 1; }
 
        /// packet loss as factor
        float PacketLoss() const noexcept { return packet_loss; }
index 0a5dcd034db106e0b868ae8fe82b9a9505636a5d..16beccf7aecb100471185aca85cd684023e2d6c8 100644 (file)
@@ -90,6 +90,8 @@ private:
 
        void SendSpawn(SpawnStatus &);
        void SendDespawn(SpawnStatus &);
+       /// true if updates are pushed to the client this frame
+       bool SendingUpdates() const noexcept;
        void QueueUpdate(SpawnStatus &);
        void SendUpdates();
 
@@ -106,6 +108,7 @@ private:
        unsigned int confirm_wait;
 
        std::vector<SpawnStatus *> entity_updates;
+       unsigned int entity_updates_skipped;
 
        EntityState player_update_state;
        std::uint16_t player_update_pack;
index f7c874f665fb1fbc4f38e190e045b5ae4f96a255..cd4f2003c359b1896adbf435430eae8b68fd3562 100644 (file)
@@ -180,6 +180,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 +212,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 +309,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 +321,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 +345,7 @@ void ClientConnection::SendUpdates() {
                Send(Packet::EntityUpdate::GetSize(entity_pos));
        }
        entity_updates.clear();
+       entity_updates_skipped = 0;
 }
 
 void ClientConnection::CheckPlayerFix() {