]> git.localhorst.tv Git - blank.git/blobdiff - src/net/net.cpp
add packet for merging player state back to client
[blank.git] / src / net / net.cpp
index 9fe282f5138b4c7a115819834c3a2b0a44373c16..3f4bf7453eab78a0ac79b7f045026ec10114a8f0 100644 (file)
@@ -7,6 +7,9 @@
 #include "Server.hpp"
 
 #include "../app/init.hpp"
+#include "../model/CompositeModel.hpp"
+#include "../world/Entity.hpp"
+#include "../world/EntityState.hpp"
 #include "../world/World.hpp"
 
 #include <cstring>
@@ -26,6 +29,7 @@ constexpr size_t Packet::PlayerUpdate::MAX_LEN;
 constexpr size_t Packet::SpawnEntity::MAX_LEN;
 constexpr size_t Packet::DespawnEntity::MAX_LEN;
 constexpr size_t Packet::EntityUpdate::MAX_LEN;
+constexpr size_t Packet::PlayerCorrection::MAX_LEN;
 
 namespace {
 
@@ -123,7 +127,9 @@ ClientConnection::ClientConnection(Server &server, const IPaddress &addr)
 , conn(addr)
 , player(nullptr)
 , spawns()
-, confirm_wait(0) {
+, confirm_wait(0)
+, player_update_pack(0)
+, player_update_timer(1500) {
        conn.SetHandler(this);
 }
 
@@ -182,6 +188,8 @@ void ClientConnection::Update(int dt) {
                        SendDespawn(*local_iter);
                        ++local_iter;
                }
+
+               CheckPlayerFix();
        }
        if (conn.ShouldPing()) {
                conn.SendPing(server.GetPacket(), server.GetSocket());
@@ -244,6 +252,14 @@ void ClientConnection::SendUpdate(SpawnStatus &status) {
        conn.Send(server.GetPacket(), server.GetSocket());
 }
 
+void ClientConnection::CheckPlayerFix() {
+       // check always succeeds for now ;)
+       auto pack = Packet::Make<Packet::PlayerCorrection>(server.GetPacket());
+       pack.WritePacketSeq(player_update_pack);
+       pack.WritePlayer(Player());
+       conn.Send(server.GetPacket(), server.GetSocket());
+}
+
 void ClientConnection::AttachPlayer(Entity &new_player) {
        DetachPlayer();
        player = &new_player;
@@ -307,6 +323,10 @@ void ClientConnection::On(const Packet::Login &pack) {
                response.WritePlayer(*new_player);
                response.WriteWorldName(server.GetWorld().Name());
                conn.Send(server.GetPacket(), server.GetSocket());
+               // set up update tracking
+               player_update_pack = pack.Seq();
+               player_update_timer.Reset();
+               player_update_timer.Start();
        } else {
                // aw no :(
                cout << "rejected login from player \"" << name << '"' << endl;
@@ -322,7 +342,14 @@ void ClientConnection::On(const Packet::Part &) {
 
 void ClientConnection::On(const Packet::PlayerUpdate &pack) {
        if (!HasPlayer()) return;
-       pack.ReadPlayer(Player());
+       int pack_diff = int16_t(pack.Seq()) - int16_t(player_update_pack);
+       bool overdue = player_update_timer.HitOnce();
+       player_update_timer.Reset();
+       if (pack_diff > 0 || overdue) {
+               player_update_pack = pack.Seq();
+               // TODO: do client input validation here
+               pack.ReadPlayerState(Player().GetState());
+       }
 }
 
 
@@ -475,6 +502,8 @@ const char *Packet::Type2String(uint8_t t) noexcept {
                        return "DespawnEntity";
                case EntityUpdate::TYPE:
                        return "EntityUpdate";
+               case PlayerCorrection::TYPE:
+                       return "PlayerCorrection";
                default:
                        return "Unknown";
        }
@@ -529,34 +558,15 @@ void Packet::Login::ReadPlayerName(string &name) const noexcept {
 
 void Packet::Join::WritePlayer(const Entity &player) noexcept {
        Write(player.ID(), 0);
-       Write(player.ChunkCoords(), 4);
-       Write(player.Position(), 16);
-       Write(player.Velocity(), 28);
-       Write(player.Orientation(), 40);
-       Write(player.AngularVelocity(), 56);
+       Write(player.GetState(), 4);
 }
 
 void Packet::Join::ReadPlayerID(uint32_t &id) const noexcept {
        Read(id, 0);
 }
 
-void Packet::Join::ReadPlayer(Entity &player) const noexcept {
-       glm::ivec3 chunk_coords(0);
-       glm::vec3 pos;
-       glm::vec3 vel;
-       glm::quat rot;
-       glm::vec3 ang;
-
-       Read(chunk_coords, 4);
-       Read(pos, 16);
-       Read(vel, 28);
-       Read(rot, 40);
-       Read(ang, 56);
-
-       player.Position(chunk_coords, pos);
-       player.Velocity(vel);
-       player.Orientation(rot);
-       player.AngularVelocity(ang);
+void Packet::Join::ReadPlayerState(EntityState &state) const noexcept {
+       Read(state, 4);
 }
 
 void Packet::Join::WriteWorldName(const string &name) noexcept {
@@ -568,75 +578,50 @@ void Packet::Join::ReadWorldName(string &name) const noexcept {
 }
 
 void Packet::PlayerUpdate::WritePlayer(const Entity &player) noexcept {
-       Write(player.ChunkCoords(), 0);
-       Write(player.Position(), 12);
-       Write(player.Velocity(), 24);
-       Write(player.Orientation(), 36);
-       Write(player.AngularVelocity(), 52);
+       Write(player.GetState(), 0);
 }
 
-void Packet::PlayerUpdate::ReadPlayer(Entity &player) const noexcept {
-       glm::ivec3 chunk_coords(0);
-       glm::vec3 pos;
-       glm::vec3 vel;
-       glm::quat rot;
-       glm::vec3 ang;
-
-       Read(chunk_coords, 0);
-       Read(pos, 12);
-       Read(vel, 24);
-       Read(rot, 36);
-       Read(ang, 52);
-
-       player.Position(chunk_coords, pos);
-       player.Velocity(vel);
-       player.Orientation(rot);
-       player.AngularVelocity(ang);
+void Packet::PlayerUpdate::ReadPlayerState(EntityState &state) const noexcept {
+       Read(state, 0);
 }
 
 void Packet::SpawnEntity::WriteEntity(const Entity &e) noexcept {
        Write(e.ID(), 0);
-       Write(e.ChunkCoords(), 4);
-       Write(e.Position(), 16);
-       Write(e.Velocity(), 28);
-       Write(e.Orientation(), 40);
-       Write(e.AngularVelocity(), 56);
-       Write(e.Bounds(), 68);
+       if (e.GetModel()) {
+               Write(e.GetModel().GetModel().ID(), 4);
+       } else {
+               Write(uint32_t(0), 4);
+       }
+       Write(e.GetState(), 8);
+       Write(e.Bounds(), 72);
        uint32_t flags = 0;
        if (e.WorldCollidable()) {
                flags |= 1;
        }
-       Write(flags, 92);
-       WriteString(e.Name(), 96, 32);
+       Write(flags, 96);
+       WriteString(e.Name(), 100, 32);
 }
 
 void Packet::SpawnEntity::ReadEntityID(uint32_t &id) const noexcept {
        Read(id, 0);
 }
 
+void Packet::SpawnEntity::ReadSkeletonID(uint32_t &id) const noexcept {
+       Read(id, 4);
+}
+
 void Packet::SpawnEntity::ReadEntity(Entity &e) const noexcept {
-       glm::ivec3 chunk_coords(0);
-       glm::vec3 pos;
-       glm::vec3 vel;
-       glm::quat rot;
-       glm::vec3 ang;
+       EntityState state;
        AABB bounds;
        uint32_t flags = 0;
        string name;
 
-       Read(chunk_coords, 4);
-       Read(pos, 16);
-       Read(vel, 28);
-       Read(rot, 40);
-       Read(ang, 56);
-       Read(bounds, 68);
-       Read(flags, 92);
-       ReadString(name, 96, 32);
-
-       e.Position(chunk_coords, pos);
-       e.Velocity(vel);
-       e.Orientation(rot);
-       e.AngularVelocity(ang);
+       Read(state, 8);
+       Read(bounds, 72);
+       Read(flags, 96);
+       ReadString(name, 100, 32);
+
+       e.SetState(state);
        e.Bounds(bounds);
        e.WorldCollidable(flags & 1);
        e.Name(name);
@@ -662,36 +647,32 @@ void Packet::EntityUpdate::WriteEntity(const Entity &entity, uint32_t num) noexc
        uint32_t off = 4 + (num * 64);
 
        Write(entity.ID(), off);
-       Write(entity.ChunkCoords(), off + 4);
-       Write(entity.Position(), off + 16);
-       Write(entity.Velocity(), off + 28);
-       Write(entity.Orientation(), off + 40);
-       Write(entity.AngularVelocity(), off + 56);
+       Write(entity.GetState(), off + 4);
 }
 
 void Packet::EntityUpdate::ReadEntityID(uint32_t &id, uint32_t num) const noexcept {
        Read(id, 4 + (num * 64));
 }
 
-void Packet::EntityUpdate::ReadEntity(Entity &entity, uint32_t num) const noexcept {
+void Packet::EntityUpdate::ReadEntityState(EntityState &state, uint32_t num) const noexcept {
        uint32_t off = 4 + (num * 64);
+       Read(state, off + 4);
+}
 
-       glm::ivec3 chunk_coords(0);
-       glm::vec3 pos;
-       glm::vec3 vel;
-       glm::quat rot;
-       glm::vec3 ang;
+void Packet::PlayerCorrection::WritePacketSeq(std::uint16_t s) noexcept {
+       Write(s, 0);
+}
 
-       Read(chunk_coords, off + 4);
-       Read(pos, off + 16);
-       Read(vel, off + 28);
-       Read(rot, off + 40);
-       Read(ang, off + 56);
+void Packet::PlayerCorrection::ReadPacketSeq(std::uint16_t &s) const noexcept {
+       Read(s, 0);
+}
 
-       entity.Position(chunk_coords, pos);
-       entity.Velocity(vel);
-       entity.Orientation(rot);
-       entity.AngularVelocity(ang);
+void Packet::PlayerCorrection::WritePlayer(const Entity &player) noexcept {
+       Write(player.GetState(), 2);
+}
+
+void Packet::PlayerCorrection::ReadPlayerState(EntityState &state) const noexcept {
+       Read(state, 2);
 }
 
 
@@ -722,6 +703,9 @@ void ConnectionHandler::Handle(const UDPpacket &udp_pack) {
                case Packet::EntityUpdate::TYPE:
                        On(Packet::As<Packet::EntityUpdate>(udp_pack));
                        break;
+               case Packet::PlayerCorrection::TYPE:
+                       On(Packet::As<Packet::PlayerCorrection>(udp_pack));
+                       break;
                default:
                        // drop unknown or unhandled packets
                        break;