#include "Server.hpp"
#include "../app/init.hpp"
+#include "../io/WorldSave.hpp"
#include "../model/CompositeModel.hpp"
#include "../world/ChunkIndex.hpp"
#include "../world/Entity.hpp"
}
uint16_t ClientConnection::Send(size_t len) {
- server.GetPacket().len = len;
+ server.GetPacket().len = sizeof(Packet::Header) + len;
return Send();
}
DetachPlayer();
input.reset(new DirectInput(server.GetWorld(), player, server));
PlayerEntity().Ref();
+ if (server.GetWorldSave().Exists(player)) {
+ server.GetWorldSave().Read(player);
+ } else {
+ // TODO: spawn
+ }
old_base = PlayerChunks().Base();
Chunk::Pos begin = PlayerChunks().CoordsBegin();
void ClientConnection::DetachPlayer() {
if (!HasPlayer()) return;
cout << "player \"" << input->GetPlayer().Name() << "\" left" << endl;
+ server.GetWorldSave().Write(input->GetPlayer());
PlayerEntity().Kill();
PlayerEntity().UnRef();
input.reset();
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 WorldSave &save)
: serv_sock(nullptr)
, serv_pack{ -1, nullptr, 0 }
, clients()
, world(world)
+, save(save)
, player_model(nullptr) {
serv_sock = SDLNet_UDP_Open(conf.port);
if (!serv_sock) {
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();
+ }
+ }
}
}