X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fserver%2Fnet.cpp;h=68880c7d6fce87ab7b9f1db1f461b752e6bd24b5;hb=8fdc24f0b3fb287f5d4e1c7d1f85ad85d5ed2414;hp=0cf0cdd60cc12ad6b9ab36d1a50745cf85c0999f;hpb=8ae45b6555d55f301f83daf8c1337d332d8305ab;p=blank.git diff --git a/src/server/net.cpp b/src/server/net.cpp index 0cf0cdd..68880c7 100644 --- a/src/server/net.cpp +++ b/src/server/net.cpp @@ -3,6 +3,7 @@ #include "Server.hpp" #include "../app/init.hpp" +#include "../model/CompositeModel.hpp" #include "../world/ChunkIndex.hpp" #include "../world/Entity.hpp" #include "../world/World.hpp" @@ -172,8 +173,10 @@ ClientConnection::ClientConnection(Server &server, const IPaddress &addr) : server(server) , conn(addr) , player(nullptr, nullptr) +, player_model(nullptr) , spawns() , confirm_wait(0) +, entity_updates() , player_update_state() , player_update_pack(0) , player_update_timer(1500) @@ -206,7 +209,7 @@ void ClientConnection::Update(int dt) { SendDespawn(*local_iter); } else { // update - SendUpdate(*local_iter); + QueueUpdate(*local_iter); } ++global_iter; ++local_iter; @@ -238,6 +241,7 @@ void ClientConnection::Update(int dt) { SendDespawn(*local_iter); ++local_iter; } + SendUpdates(); CheckPlayerFix(); CheckChunkQueue(); @@ -300,15 +304,31 @@ void ClientConnection::SendDespawn(SpawnStatus &status) { ++confirm_wait; } -void ClientConnection::SendUpdate(SpawnStatus &status) { +void ClientConnection::QueueUpdate(SpawnStatus &status) { // don't send updates while spawn not ack'd or despawn sent - if (status.spawn_pack != -1 || status.despawn_pack != -1) return; + if (status.spawn_pack == -1 && status.despawn_pack == -1) { + entity_updates.push_back(&status); + } +} - // TODO: pack entity updates +void ClientConnection::SendUpdates() { auto pack = Prepare(); - pack.WriteEntityCount(1); - pack.WriteEntity(*status.entity, 0); - Send(Packet::EntityUpdate::GetSize(1)); + int entity_pos = 0; + for (SpawnStatus *status : entity_updates) { + pack.WriteEntity(*status->entity, entity_pos); + ++entity_pos; + if (entity_pos == Packet::EntityUpdate::MAX_ENTITIES) { + pack.WriteEntityCount(entity_pos); + Send(Packet::EntityUpdate::GetSize(entity_pos)); + pack = Prepare(); + entity_pos = 0; + } + } + if (entity_pos > 0) { + pack.WriteEntityCount(entity_pos); + Send(Packet::EntityUpdate::GetSize(entity_pos)); + } + entity_updates.clear(); } void ClientConnection::CheckPlayerFix() { @@ -382,6 +402,9 @@ void ClientConnection::AttachPlayer(const Player &new_player) { } } } + if (HasPlayerModel()) { + GetPlayerModel().Instantiate(player.entity->GetModel()); + } cout << "player \"" << player.entity->Name() << "\" joined" << endl; } @@ -397,6 +420,21 @@ void ClientConnection::DetachPlayer() { chunk_queue.clear(); } +void ClientConnection::SetPlayerModel(const CompositeModel &m) noexcept { + player_model = &m; + if (HasPlayer()) { + m.Instantiate(PlayerEntity().GetModel()); + } +} + +bool ClientConnection::HasPlayerModel() const noexcept { + return player_model; +} + +const CompositeModel &ClientConnection::GetPlayerModel() const noexcept { + return *player_model; +} + void ClientConnection::OnPacketReceived(uint16_t seq) { if (transmitter.Waiting()) { transmitter.Ack(seq); @@ -488,7 +526,8 @@ Server::Server(const Config &conf, World &world) : serv_sock(nullptr) , serv_pack{ -1, nullptr, 0 } , clients() -, world(world) { +, world(world) +, player_model(nullptr) { serv_sock = SDLNet_UDP_Open(conf.port); if (!serv_sock) { throw NetError("SDLNet_UDP_Open"); @@ -538,12 +577,14 @@ ClientConnection &Server::GetClient(const IPaddress &addr) { } } clients.emplace_back(*this, addr); + if (HasPlayerModel()) { + clients.back().SetPlayerModel(GetPlayerModel()); + } return clients.back(); } void Server::Update(int dt) { for (list::iterator client(clients.begin()), end(clients.end()); client != end;) { - client->Update(dt); if (client->Disconnected()) { client = clients.erase(client); } else { @@ -552,5 +593,20 @@ void Server::Update(int dt) { } } +void Server::SetPlayerModel(const CompositeModel &m) noexcept { + player_model = &m; + for (ClientConnection &client : clients) { + client.SetPlayerModel(m); + } +} + +bool Server::HasPlayerModel() const noexcept { + return player_model; +} + +const CompositeModel &Server::GetPlayerModel() const noexcept { + return *player_model; +} + } }