]> git.localhorst.tv Git - blank.git/blobdiff - src/server/net.cpp
rearrange init of standalone state a little
[blank.git] / src / server / net.cpp
index ea5b4d995f19d38262891b0919f1fb2360ed05b3..1e60ff6ead06d3dfd7905946866d4d4920ead0fd 100644 (file)
@@ -3,6 +3,7 @@
 #include "Server.hpp"
 
 #include "../app/init.hpp"
+#include "../io/WorldSave.hpp"
 #include "../model/CompositeModel.hpp"
 #include "../world/ChunkIndex.hpp"
 #include "../world/Entity.hpp"
@@ -283,7 +284,7 @@ uint16_t ClientConnection::Send() {
 }
 
 uint16_t ClientConnection::Send(size_t len) {
-       server.GetPacket().len = len;
+       server.GetPacket().len = sizeof(Packet::Header) + len;
        return Send();
 }
 
@@ -405,6 +406,7 @@ void ClientConnection::AttachPlayer(Player &player) {
                        }
                }
        }
+       // TODO: should the server do this?
        if (HasPlayerModel()) {
                GetPlayerModel().Instantiate(PlayerEntity().GetModel());
        }
@@ -415,6 +417,7 @@ void ClientConnection::AttachPlayer(Player &player) {
 void ClientConnection::DetachPlayer() {
        if (!HasPlayer()) return;
        cout << "player \"" << input->GetPlayer().Name() << "\" left" << endl;
+       server.GetWorldSave().Write(input->GetPlayer());
        PlayerEntity().Kill();
        PlayerEntity().UnRef();
        input.reset();
@@ -482,7 +485,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!
@@ -555,12 +558,22 @@ void ClientConnection::On(const Packet::PlayerUpdate &pack) {
        old_actions = new_actions;
 }
 
+bool ClientConnection::ChunkInRange(const glm::ivec3 &pos) const noexcept {
+       return HasPlayer() && PlayerChunks().InRange(pos);
+}
+
 
-Server::Server(const Config::Network &conf, World &world)
+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);
        if (!serv_sock) {
@@ -572,6 +585,7 @@ Server::Server(const Config::Network &conf, World &world)
 }
 
 Server::~Server() {
+       world.Chunks().UnregisterIndex(spawn_index);
        delete[] serv_pack.data;
        SDLNet_UDP_Close(serv_sock);
 }
@@ -643,10 +657,36 @@ 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: send to clients
-       // also TODO: batch chunk changes
+       // TODO: batch chunk changes
+       auto pack = Packet::Make<Packet::BlockUpdate>(GetPacket());
+       pack.WriteChunkCoords(chunk.Position());
+       pack.WriteBlockCount(uint32_t(1));
+       pack.WriteIndex(index, 0);
+       pack.WriteBlock(chunk.BlockAt(index), 0);
+       GetPacket().len = sizeof(Packet::Header) + Packet::BlockUpdate::GetSize(1);
+       for (ClientConnection &client : clients) {
+               if (client.ChunkInRange(chunk.Position())) {
+                       client.Send();
+               }
+       }
 }
 
 }