X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fclient%2Fnet.cpp;h=18f593ac5831d218f0019723c511ff977a7e2ffe;hb=b9462143d9b2fd1f54aa3b4ec32eecb62c01615f;hp=7d8681aecd15f1a4b324bfb2614423a4f3b13808;hpb=d30497e8e16c8470ce2f9f0b245befd196ea4660;p=blank.git diff --git a/src/client/net.cpp b/src/client/net.cpp index 7d8681a..18f593a 100644 --- a/src/client/net.cpp +++ b/src/client/net.cpp @@ -4,6 +4,7 @@ #include "NetworkedInput.hpp" #include "../app/init.hpp" +#include "../io/WorldSave.hpp" #include "../net/Packet.hpp" #include "../world/Chunk.hpp" #include "../world/ChunkStore.hpp" @@ -21,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(); @@ -48,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); @@ -244,14 +288,12 @@ 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); pack.WriteMovement(movement); - pack.WritePitch(pitch); - pack.WriteYaw(yaw); pack.WriteActions(actions); pack.WriteSlot(slot); return conn.Send(client_pack, client_sock); @@ -262,16 +304,34 @@ uint16_t Client::SendPart() { return conn.Send(client_pack, client_sock); } +uint16_t Client::SendMessage( + uint8_t type, + uint32_t ref, + const string &msg +) { + auto pack = Packet::Make(client_pack); + pack.WriteType(type); + pack.WriteReferral(ref); + pack.WriteMessage(msg); + client_pack.len = sizeof(Packet::Header) + Packet::Message::GetSize(msg); + return conn.Send(client_pack, client_sock); +} NetworkedInput::NetworkedInput(World &world, Player &player, Client &client) : PlayerController(world, player) , client(client) , player_hist() +, old_movement(0.0f) +, old_actions(0) , actions(0) { } -void NetworkedInput::Update(int dt) { +bool NetworkedInput::UpdateImportant() const noexcept { + return old_actions != actions || !iszero(old_movement - GetMovement()); +} + +void NetworkedInput::Update(Entity &, float dt) { Invalidate(); UpdatePlayer(); } @@ -279,7 +339,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(), @@ -288,14 +348,17 @@ void NetworkedInput::PushPlayerUpdate(int dt) { InventorySlot() ); if (player_hist.size() < 16) { - player_hist.emplace_back(state, dt, packet); + player_hist.emplace_back(state, GetMovement(), dt * 0.001f, packet); } else { auto entry = player_hist.begin(); entry->state = state; - entry->delta_t = dt; + entry->movement = GetMovement(); + entry->delta_t = dt * 0.001f; 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) { @@ -321,7 +384,9 @@ void NetworkedInput::MergePlayerCorrection(uint16_t seq, const EntityState &corr } } - EntityState &player_state = GetPlayer().GetEntity().GetState(); + glm::vec3 restore_movement(GetMovement()); + + EntityState player_state = GetPlayer().GetEntity().GetState(); Entity replay(GetPlayer().GetEntity()); replay.SetState(corrected_state); @@ -334,11 +399,8 @@ void NetworkedInput::MergePlayerCorrection(uint16_t seq, const EntityState &corr vector col; while (entry != end) { replay.Velocity(entry->state.velocity); - replay.Update(entry->delta_t); - if (GetWorld().Intersection(replay, col)) { - GetWorld().Resolve(replay, col); - col.clear(); - } + SetMovement(entry->movement); + GetWorld().Update(replay, entry->delta_t); entry->state.chunk_pos = replay.GetState().chunk_pos; entry->state.block_pos = replay.GetState().block_pos; ++entry; @@ -348,6 +410,7 @@ void NetworkedInput::MergePlayerCorrection(uint16_t seq, const EntityState &corr const float disp_squared = dot(displacement, displacement); if (disp_squared < 16.0f * numeric_limits::epsilon()) { + SetMovement(restore_movement); return; } @@ -366,6 +429,8 @@ void NetworkedInput::MergePlayerCorrection(uint16_t seq, const EntityState &corr displacement *= 0.01f / sqrt(disp_squared); player_state.block_pos += displacement; } + GetPlayer().GetEntity().SetState(player_state); + SetMovement(restore_movement); } void NetworkedInput::StartPrimaryAction() {