]> git.localhorst.tv Git - blank.git/blobdiff - src/server/net.cpp
transmit chunks in growing sphere order
[blank.git] / src / server / net.cpp
index 7cb07cdf02b9ae1e6f026493f20e0dd5aed65707..27643ee8fc34abb4d9b18c0b2b47f0837df7f491 100644 (file)
@@ -9,6 +9,7 @@
 #include "../world/Entity.hpp"
 #include "../world/World.hpp"
 
+#include <algorithm>
 #include <iostream>
 #include <zlib.h>
 #include <glm/gtx/io.hpp>
@@ -352,6 +353,23 @@ void ClientConnection::CheckPlayerFix() {
        }
 }
 
+namespace {
+
+struct QueueCompare {
+       explicit QueueCompare(const glm::ivec3 &base)
+       : base(base) { }
+       bool operator ()(const glm::ivec3 &left, const glm::ivec3 &right) const noexcept {
+               const glm::ivec3 ld(left - base);
+               const glm::ivec3 rd(right - base);
+               return
+                       ld.x * ld.x + ld.y * ld.y + ld.z * ld.z <
+                       rd.x * rd.x + rd.y * rd.y + rd.z * rd.z;
+       }
+       const glm::ivec3 &base;
+};
+
+}
+
 void ClientConnection::CheckChunkQueue() {
        if (PlayerChunks().Base() != old_base) {
                Chunk::Pos begin = PlayerChunks().CoordsBegin();
@@ -366,6 +384,7 @@ void ClientConnection::CheckChunkQueue() {
                        }
                }
                old_base = PlayerChunks().Base();
+               sort(chunk_queue.begin(), chunk_queue.end(), QueueCompare(old_base));
        }
        if (transmitter.Transmitting()) {
                transmitter.Transmit();
@@ -395,9 +414,6 @@ void ClientConnection::AttachPlayer(Player &player) {
        DetachPlayer();
        input.reset(new DirectInput(server.GetWorld(), player, server));
        PlayerEntity().Ref();
-       if (server.GetWorldSave().Exists(player)) {
-               server.GetWorldSave().Read(player);
-       }
 
        old_base = PlayerChunks().Base();
        Chunk::Pos begin = PlayerChunks().CoordsBegin();
@@ -409,6 +425,8 @@ void ClientConnection::AttachPlayer(Player &player) {
                        }
                }
        }
+       sort(chunk_queue.begin(), chunk_queue.end(), QueueCompare(old_base));
+       // TODO: should the server do this?
        if (HasPlayerModel()) {
                GetPlayerModel().Instantiate(PlayerEntity().GetModel());
        }
@@ -487,7 +505,7 @@ void ClientConnection::On(const Packet::Login &pack) {
        string name;
        pack.ReadPlayerName(name);
 
-       Player *new_player = server.GetWorld().AddPlayer(name);
+       Player *new_player = server.JoinPlayer(name);
 
        if (new_player) {
                // success!
@@ -565,11 +583,16 @@ bool ClientConnection::ChunkInRange(const glm::ivec3 &pos) const noexcept {
 }
 
 
-Server::Server(const Config::Network &conf, World &world, const WorldSave &save)
+Server::Server(
+       const Config::Network &conf,
+       World &world,
+       const World::Config &wc,
+       const WorldSave &save)
 : serv_sock(nullptr)
 , serv_pack{ -1, nullptr, 0 }
 , clients()
 , world(world)
+, spawn_index(world.Chunks().MakeIndex(wc.spawn, 3))
 , save(save)
 , player_model(nullptr) {
        serv_sock = SDLNet_UDP_Open(conf.port);
@@ -582,6 +605,7 @@ Server::Server(const Config::Network &conf, World &world, const WorldSave &save)
 }
 
 Server::~Server() {
+       world.Chunks().UnregisterIndex(spawn_index);
        delete[] serv_pack.data;
        SDLNet_UDP_Close(serv_sock);
 }
@@ -653,6 +677,22 @@ const CompositeModel &Server::GetPlayerModel() const noexcept {
        return *player_model;
 }
 
+Player *Server::JoinPlayer(const string &name) {
+       if (spawn_index.MissingChunks() > 0) {
+               return nullptr;
+       }
+       Player *player = world.AddPlayer(name);
+       if (!player) {
+               return nullptr;
+       }
+       if (save.Exists(*player)) {
+               save.Read(*player);
+       } else {
+               // TODO: spawn
+       }
+       return player;
+}
+
 void Server::SetBlock(Chunk &chunk, int index, const Block &block) {
        chunk.SetBlock(index, block);
        // TODO: batch chunk changes