X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fserver%2Fnet.cpp;h=ea5b4d995f19d38262891b0919f1fb2360ed05b3;hb=c1da86ebab41895bf49ed747c75ecf722e8c5586;hp=68880c7d6fce87ab7b9f1db1f461b752e6bd24b5;hpb=8fdc24f0b3fb287f5d4e1c7d1f85ad85d5ed2414;p=blank.git diff --git a/src/server/net.cpp b/src/server/net.cpp index 68880c7..ea5b4d9 100644 --- a/src/server/net.cpp +++ b/src/server/net.cpp @@ -10,6 +10,7 @@ #include #include +#include using namespace std; @@ -172,7 +173,7 @@ void ChunkTransmitter::Release() { ClientConnection::ClientConnection(Server &server, const IPaddress &addr) : server(server) , conn(addr) -, player(nullptr, nullptr) +, input() , player_model(nullptr) , spawns() , confirm_wait(0) @@ -180,6 +181,7 @@ ClientConnection::ClientConnection(Server &server, const IPaddress &addr) , player_update_state() , player_update_pack(0) , player_update_timer(1500) +, old_actions(0) , transmitter(*this) , chunk_queue() , old_base() { @@ -243,6 +245,7 @@ void ClientConnection::Update(int dt) { } SendUpdates(); + input->Update(dt); CheckPlayerFix(); CheckChunkQueue(); } @@ -264,7 +267,7 @@ ClientConnection::SpawnStatus::~SpawnStatus() { bool ClientConnection::CanSpawn(const Entity &e) const noexcept { return - &e != player.entity && + &e != &PlayerEntity() && !e.Dead() && manhattan_radius(e.ChunkCoords() - PlayerEntity().ChunkCoords()) < 7; } @@ -387,14 +390,14 @@ void ClientConnection::CheckChunkQueue() { } } -void ClientConnection::AttachPlayer(const Player &new_player) { +void ClientConnection::AttachPlayer(Player &player) { DetachPlayer(); - player = new_player; - player.entity->Ref(); + input.reset(new DirectInput(server.GetWorld(), player, server)); + PlayerEntity().Ref(); - old_base = player.chunks->Base(); - Chunk::Pos begin = player.chunks->CoordsBegin(); - Chunk::Pos end = player.chunks->CoordsEnd(); + old_base = PlayerChunks().Base(); + Chunk::Pos begin = PlayerChunks().CoordsBegin(); + Chunk::Pos end = PlayerChunks().CoordsEnd(); for (Chunk::Pos pos = begin; pos.z < end.z; ++pos.z) { for (pos.y = begin.y; pos.y < end.y; ++pos.y) { for (pos.x = begin.x; pos.x < end.x; ++pos.x) { @@ -403,21 +406,21 @@ void ClientConnection::AttachPlayer(const Player &new_player) { } } if (HasPlayerModel()) { - GetPlayerModel().Instantiate(player.entity->GetModel()); + GetPlayerModel().Instantiate(PlayerEntity().GetModel()); } - cout << "player \"" << player.entity->Name() << "\" joined" << endl; + cout << "player \"" << player.Name() << "\" joined" << endl; } void ClientConnection::DetachPlayer() { if (!HasPlayer()) return; - cout << "player \"" << player.entity->Name() << "\" left" << endl; - player.entity->Kill(); - player.entity->UnRef(); - player.entity = nullptr; - player.chunks = nullptr; + cout << "player \"" << input->GetPlayer().Name() << "\" left" << endl; + PlayerEntity().Kill(); + PlayerEntity().UnRef(); + input.reset(); transmitter.Abort(); chunk_queue.clear(); + old_actions = 0; } void ClientConnection::SetPlayerModel(const CompositeModel &m) noexcept { @@ -479,18 +482,18 @@ void ClientConnection::On(const Packet::Login &pack) { string name; pack.ReadPlayerName(name); - Player new_player = server.GetWorld().AddPlayer(name); + Player *new_player = server.GetWorld().AddPlayer(name); - if (new_player.entity) { + if (new_player) { // success! - AttachPlayer(new_player); + AttachPlayer(*new_player); cout << "accepted login from player \"" << name << '"' << endl; auto response = Prepare(); - response.WritePlayer(*new_player.entity); + response.WritePlayer(new_player->GetEntity()); response.WriteWorldName(server.GetWorld().Name()); Send(); // set up update tracking - player_update_state = new_player.entity->GetState(); + player_update_state = new_player->GetEntity().GetState(); player_update_pack = pack.Seq(); player_update_timer.Reset(); player_update_timer.Start(); @@ -512,17 +515,48 @@ void ClientConnection::On(const Packet::PlayerUpdate &pack) { 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(); - pack.ReadPlayerState(player_update_state); - // accept velocity and orientation as "user input" - PlayerEntity().Velocity(player_update_state.velocity); - PlayerEntity().Orientation(player_update_state.orient); + if (pack_diff <= 0 && !overdue) { + // drop old packets if we have a fairly recent state + return; + } + glm::vec3 movement(0.0f); + float pitch = 0.0f; + float yaw = 0.0f; + uint8_t new_actions; + uint8_t slot; + + player_update_pack = pack.Seq(); + pack.ReadPredictedState(player_update_state); + pack.ReadMovement(movement); + pack.ReadPitch(pitch); + pack.ReadYaw(yaw); + pack.ReadActions(new_actions); + pack.ReadSlot(slot); + + input->SetMovement(movement); + input->TurnHead(pitch - input->GetPitch(), yaw - input->GetYaw()); + input->SelectInventory(slot); + + if ((new_actions & 0x01) && !(old_actions & 0x01)) { + input->StartPrimaryAction(); + } else if (!(new_actions & 0x01) && (old_actions & 0x01)) { + input->StopPrimaryAction(); + } + if ((new_actions & 0x02) && !(old_actions & 0x02)) { + input->StartSecondaryAction(); + } else if (!(new_actions & 0x02) && (old_actions & 0x02)) { + input->StopSecondaryAction(); + } + if ((new_actions & 0x04) && !(old_actions & 0x04)) { + input->StartTertiaryAction(); + } else if (!(new_actions & 0x04) && (old_actions & 0x04)) { + input->StopTertiaryAction(); } + old_actions = new_actions; } -Server::Server(const Config &conf, World &world) +Server::Server(const Config::Network &conf, World &world) : serv_sock(nullptr) , serv_pack{ -1, nullptr, 0 } , clients() @@ -585,6 +619,7 @@ ClientConnection &Server::GetClient(const IPaddress &addr) { 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 { @@ -608,5 +643,11 @@ const CompositeModel &Server::GetPlayerModel() const noexcept { return *player_model; } +void Server::SetBlock(Chunk &chunk, int index, const Block &block) { + chunk.SetBlock(index, block); + // TODO: send to clients + // also TODO: batch chunk changes +} + } }