]> git.localhorst.tv Git - blank.git/blobdiff - src/client/net.cpp
move common exceptions to app/error
[blank.git] / src / client / net.cpp
index d7a2661d56c3bc54d09df6140da9a003fed848db..879dfb10ef8908cc30f3b4a07f62d50318e2b2a5 100644 (file)
@@ -3,7 +3,7 @@
 #include "Client.hpp"
 #include "NetworkedInput.hpp"
 
-#include "../app/init.hpp"
+#include "../app/error.hpp"
 #include "../geometry/distance.hpp"
 #include "../io/WorldSave.hpp"
 #include "../net/Packet.hpp"
@@ -23,8 +23,9 @@ namespace blank {
 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) {
@@ -40,7 +41,14 @@ void ChunkReceiver::Update(int dt) {
        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) {
@@ -152,7 +160,7 @@ void ChunkReceiver::Commit(ChunkTransmission &trans) {
 
        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;
@@ -167,10 +175,17 @@ void ChunkReceiver::Commit(ChunkTransmission &trans) {
                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();
 }
@@ -188,11 +203,15 @@ ChunkTransmission::ChunkTransmission()
 
 }
 
-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;
 }
 
@@ -225,10 +244,15 @@ IPaddress client_resolve(const char *host, Uint16 port) {
 
 }
 
+// relying on {} zero intitialization for UDPpacket, because
+// the type and number of fields is not well defined
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
 Client::Client(const Config::Network &conf)
 : conn(client_resolve(conf.host.c_str(), conf.port))
 , client_sock(client_bind(0))
 , client_pack{ -1, nullptr, 0 } {
+#pragma GCC diagnostic pop
        client_pack.data = new Uint8[sizeof(Packet)];
        client_pack.maxlen = sizeof(Packet);
        // establish connection
@@ -287,8 +311,8 @@ uint16_t Client::SendLogin(const string &name) {
 uint16_t Client::SendPlayerUpdate(
        const EntityState &prediction,
        const glm::vec3 &movement,
-       float pitch,
-       float yaw,
+       float,
+       float,
        uint8_t actions,
        uint8_t slot
 ) {
@@ -305,6 +329,14 @@ uint16_t Client::SendPart() {
        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,
@@ -332,7 +364,7 @@ bool NetworkedInput::UpdateImportant() const noexcept {
        return old_actions != actions || !iszero(old_movement - GetMovement());
 }
 
-void NetworkedInput::Update(Entity &, float dt) {
+void NetworkedInput::Update(Entity &, float) {
        Invalidate();
        UpdatePlayer();
 }
@@ -399,13 +431,13 @@ void NetworkedInput::MergePlayerCorrection(uint16_t seq, const EntityState &corr
        vector<WorldCollision> col;
        while (entry != end) {
                SetMovement(entry->movement);
-               GetWorld().Update(replay, entry->delta_t);
+               replay.Update(GetWorld(), entry->delta_t);
                entry->state.pos = replay.GetState().pos;
                ++entry;
        }
 
        glm::vec3 displacement(replay.GetState().Diff(player_state));
-       const float disp_squared = dot(displacement, displacement);
+       const float disp_squared = glm::dot(displacement, displacement);
 
        if (disp_squared < 16.0f * numeric_limits<float>::epsilon()) {
                SetMovement(restore_movement);