X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fclient%2Fnet.cpp;h=8a4930410605b7a8eacf0ae0dd8886ef2630ad51;hb=8639a90bcbcd045c57cd489f02a25e0df4236deb;hp=6e8d00cc69de3922c063d912fdf34b82b46927b1;hpb=c1da86ebab41895bf49ed747c75ecf722e8c5586;p=blank.git diff --git a/src/client/net.cpp b/src/client/net.cpp index 6e8d00c..8a49304 100644 --- a/src/client/net.cpp +++ b/src/client/net.cpp @@ -4,10 +4,12 @@ #include "NetworkedInput.hpp" #include "../app/init.hpp" +#include "../io/WorldSave.hpp" #include "../net/Packet.hpp" #include "../world/Chunk.hpp" #include "../world/ChunkStore.hpp" #include "../world/Player.hpp" +#include "../world/World.hpp" #include #include @@ -20,8 +22,9 @@ namespace blank { namespace client { -ChunkReceiver::ChunkReceiver(ChunkStore &store) +ChunkReceiver::ChunkReceiver(ChunkStore &store, const WorldSave &save) : store(store) +, save(save) , transmissions() , timer(5000) { timer.Start(); @@ -47,8 +50,50 @@ void ChunkReceiver::Update(int dt) { } } } + LoadN(10); + StoreN(10); } +int ChunkReceiver::ToLoad() const noexcept { + return store.EstimateMissing(); +} + +void ChunkReceiver::LoadOne() { + if (!store.HasMissing()) return; + + Chunk::Pos pos = store.NextMissing(); + Chunk *chunk = store.Allocate(pos); + if (!chunk) { + // chunk store corrupted? + return; + } + + if (save.Exists(pos)) { + save.Read(*chunk); + } +} + +void ChunkReceiver::LoadN(size_t n) { + size_t end = min(n, size_t(ToLoad())); + for (size_t i = 0; i < end && store.HasMissing(); ++i) { + LoadOne(); + } +} + +void ChunkReceiver::StoreN(size_t n) { + size_t saved = 0; + for (Chunk &chunk : store) { + if (chunk.ShouldUpdateSave()) { + save.Write(chunk); + ++saved; + if (saved >= n) { + break; + } + } + } +} + + void ChunkReceiver::Handle(const Packet::ChunkBegin &pack) { uint32_t id; pack.ReadTransmissionId(id); @@ -243,8 +288,8 @@ uint16_t Client::SendPlayerUpdate( const glm::vec3 &movement, float pitch, float yaw, - std::uint8_t actions, - std::uint8_t slot + uint8_t actions, + uint8_t slot ) { auto pack = Packet::Make(client_pack); pack.WritePredictedState(prediction); @@ -278,7 +323,7 @@ void NetworkedInput::Update(int dt) { void NetworkedInput::PushPlayerUpdate(int dt) { const EntityState &state = GetPlayer().GetEntity().GetState(); - std::uint16_t packet = client.SendPlayerUpdate( + uint16_t packet = client.SendPlayerUpdate( state, GetMovement(), GetPitch(), @@ -287,10 +332,11 @@ void NetworkedInput::PushPlayerUpdate(int dt) { InventorySlot() ); if (player_hist.size() < 16) { - player_hist.emplace_back(state, dt, packet); + player_hist.emplace_back(state, GetPlayer().GetEntity().TargetVelocity(), dt, packet); } else { auto entry = player_hist.begin(); entry->state = state; + entry->tgt_vel = GetPlayer().GetEntity().TargetVelocity(); entry->delta_t = dt; entry->packet = packet; player_hist.splice(player_hist.end(), player_hist, entry); @@ -320,24 +366,27 @@ void NetworkedInput::MergePlayerCorrection(uint16_t seq, const EntityState &corr } } - EntityState replay_state(corrected_state); EntityState &player_state = GetPlayer().GetEntity().GetState(); + Entity replay(GetPlayer().GetEntity()); + replay.SetState(corrected_state); if (entry != end) { - entry->state.chunk_pos = replay_state.chunk_pos; - entry->state.block_pos = replay_state.block_pos; + entry->state.chunk_pos = replay.GetState().chunk_pos; + entry->state.block_pos = replay.GetState().block_pos; ++entry; } + vector col; while (entry != end) { - replay_state.velocity = entry->state.velocity; - replay_state.Update(entry->delta_t); - entry->state.chunk_pos = replay_state.chunk_pos; - entry->state.block_pos = replay_state.block_pos; + replay.Velocity(entry->state.velocity); + replay.TargetVelocity(entry->tgt_vel); + GetWorld().Update(replay, entry->delta_t); + entry->state.chunk_pos = replay.GetState().chunk_pos; + entry->state.block_pos = replay.GetState().block_pos; ++entry; } - glm::vec3 displacement(replay_state.Diff(player_state)); + glm::vec3 displacement(replay.GetState().Diff(player_state)); const float disp_squared = dot(displacement, displacement); if (disp_squared < 16.0f * numeric_limits::epsilon()) { @@ -351,8 +400,8 @@ void NetworkedInput::MergePlayerCorrection(uint16_t seq, const EntityState &corr constexpr float max_disp = 0.0001f; // (1/100)^2 if (disp_squared > warp_thresh) { - player_state.chunk_pos = replay_state.chunk_pos; - player_state.block_pos = replay_state.block_pos; + player_state.chunk_pos = replay.GetState().chunk_pos; + player_state.block_pos = replay.GetState().block_pos; } else if (disp_squared < max_disp) { player_state.block_pos += displacement; } else {