#include "NetworkedInput.hpp"
#include "../app/init.hpp"
+#include "../geometry/distance.hpp"
#include "../io/WorldSave.hpp"
#include "../net/Packet.hpp"
#include "../world/Chunk.hpp"
namespace client {
-ChunkReceiver::ChunkReceiver(ChunkStore &store, const WorldSave &save)
-: store(store)
+ChunkReceiver::ChunkReceiver(Client &client, ChunkStore &store, const WorldSave &save)
+: client(client)
+, store(store)
, save(save)
, transmissions()
, timer(5000) {
for (ChunkTransmission &trans : transmissions) {
if (trans.active && (timer.Elapsed() - trans.last_update) > timer.Interval()) {
cout << "timeout for transmission of chunk " << trans.coords << endl;
- trans.Clear();
+ if (trans.header_received) {
+ client.SendChunkRequest(trans.coords);
+ trans.Reset();
+ trans.last_update = timer.Elapsed();
+ } else {
+ // well shit
+ trans.Clear();
+ }
}
}
if (transmissions.size() > 3) {
void ChunkReceiver::LoadOne() {
if (!store.HasMissing()) return;
- Chunk::Pos pos = store.NextMissing();
+ ExactLocation::Coarse pos = store.NextMissing();
Chunk *chunk = store.Allocate(pos);
if (!chunk) {
// chunk store corrupted?
Chunk *chunk = store.Allocate(trans.coords);
if (!chunk) {
- // chunk no longer of interes, just drop the data
+ // chunk no longer of interest, just drop the data
// it should probably be cached to disk, but not now :P
trans.Clear();
return;
if (uncompress(dst, &dst_len, src, src_len) != Z_OK) {
// omg, now what?
cout << "got corruped chunk data for " << trans.coords << endl;
+ client.SendChunkRequest(trans.coords);
+ trans.Reset();
+ // chunk data can, and probably will, contain invalid block IDs, so
+ // zero it to be safe
+ memset(dst, 0, dst_len);
+ return;
}
} else {
memcpy(dst, src, min(src_len, dst_len));
}
+ chunk->ScanActive();
chunk->Invalidate();
trans.Clear();
}
}
-void ChunkTransmission::Clear() noexcept {
+void ChunkTransmission::Reset() noexcept {
data_size = 0;
data_received = 0;
last_update = 0;
header_received = false;
+}
+
+void ChunkTransmission::Clear() noexcept {
+ Reset();
active = false;
}
return conn.Send(client_pack, client_sock);
}
+uint16_t Client::SendChunkRequest(
+ const glm::ivec3 &coords
+) {
+ auto pack = Packet::Make<Packet::ChunkBegin>(client_pack);
+ pack.WriteChunkCoords(coords);
+ return conn.Send(client_pack, client_sock);
+}
+
uint16_t Client::SendMessage(
uint8_t type,
uint32_t ref,
replay.SetState(corrected_state);
if (entry != end) {
- entry->state.chunk_pos = replay.GetState().chunk_pos;
- entry->state.block_pos = replay.GetState().block_pos;
+ entry->state.pos = replay.GetState().pos;
++entry;
}
vector<WorldCollision> col;
while (entry != end) {
- replay.Velocity(entry->state.velocity);
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;
+ replay.Update(GetWorld(), entry->delta_t);
+ entry->state.pos = replay.GetState().pos;
++entry;
}
constexpr float max_disp = 0.0001f; // (1/100)^2
if (disp_squared > warp_thresh) {
- player_state.chunk_pos = replay.GetState().chunk_pos;
- player_state.block_pos = replay.GetState().block_pos;
+ player_state.pos = replay.GetState().pos;
} else if (disp_squared < max_disp) {
- player_state.block_pos += displacement;
+ player_state.pos.block += displacement;
} else {
displacement *= 0.01f / sqrt(disp_squared);
- player_state.block_pos += displacement;
+ player_state.pos.block += displacement;
}
GetPlayer().GetEntity().SetState(player_state);
SetMovement(restore_movement);