From b9462143d9b2fd1f54aa3b4ec32eecb62c01615f Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Tue, 27 Oct 2015 17:15:42 +0100 Subject: [PATCH] send updates less frequently on bad connections --- src/client/InteractiveState.hpp | 3 +++ src/client/NetworkedInput.hpp | 4 ++++ src/client/client.cpp | 13 +++++++++++-- src/client/net.cpp | 8 ++++++++ src/net/CongestionControl.hpp | 2 ++ src/server/ClientConnection.hpp | 3 +++ src/server/net.cpp | 13 ++++++++++++- 7 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/client/InteractiveState.hpp b/src/client/InteractiveState.hpp index 7368e42..ac8f87b 100644 --- a/src/client/InteractiveState.hpp +++ b/src/client/InteractiveState.hpp @@ -101,6 +101,9 @@ private: ChatState chat; + int time_skipped; + unsigned int packets_skipped; + }; } diff --git a/src/client/NetworkedInput.hpp b/src/client/NetworkedInput.hpp index b557b1b..3a61d90 100644 --- a/src/client/NetworkedInput.hpp +++ b/src/client/NetworkedInput.hpp @@ -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 player_hist; + glm::vec3 old_movement; + + std::uint8_t old_actions; std::uint8_t actions; }; diff --git a/src/client/client.cpp b/src/client/client.cpp index 0eec984..d20a98c 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -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()) { diff --git a/src/client/net.cpp b/src/client/net.cpp index 6677f51..18f593a 100644 --- a/src/client/net.cpp +++ b/src/client/net.cpp @@ -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) { diff --git a/src/net/CongestionControl.hpp b/src/net/CongestionControl.hpp index ea71c55..7d4baca 100644 --- a/src/net/CongestionControl.hpp +++ b/src/net/CongestionControl.hpp @@ -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; } diff --git a/src/server/ClientConnection.hpp b/src/server/ClientConnection.hpp index 0a5dcd0..16beccf 100644 --- a/src/server/ClientConnection.hpp +++ b/src/server/ClientConnection.hpp @@ -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 entity_updates; + unsigned int entity_updates_skipped; EntityState player_update_state; std::uint16_t player_update_pack; diff --git a/src/server/net.cpp b/src/server/net.cpp index f7c874f..cd4f200 100644 --- a/src/server/net.cpp +++ b/src/server/net.cpp @@ -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(); 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() { -- 2.39.2