From 6cd00aacfa22fed6a54a9b812f6b069ad16feec0 Mon Sep 17 00:00:00 2001 From: untodesu Date: Sun, 29 Jun 2025 22:24:42 +0500 Subject: Move game sources into src subdirectory --- src/game/client/receive.cc | 187 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 src/game/client/receive.cc (limited to 'src/game/client/receive.cc') diff --git a/src/game/client/receive.cc b/src/game/client/receive.cc new file mode 100644 index 0000000..742d3af --- /dev/null +++ b/src/game/client/receive.cc @@ -0,0 +1,187 @@ +#include "client/pch.hh" + +#include "client/receive.hh" + +#include "shared/dimension.hh" +#include "shared/head.hh" +#include "shared/player.hh" +#include "shared/protocol.hh" +#include "shared/transform.hh" +#include "shared/velocity.hh" + +#include "client/chat.hh" +#include "client/factory.hh" +#include "client/globals.hh" +#include "client/gui_screen.hh" +#include "client/message_box.hh" +#include "client/session.hh" +#include "client/sound.hh" +#include "client/window_title.hh" + +static bool synchronize_entity_id(Dimension* dimension, entt::entity entity) +{ + if(dimension->entities.valid(entity)) { + // Entity ID already exists + return true; + } + + auto created = dimension->entities.create(entity); + + if(created == entity) { + // Synchronized successfully + return true; + } + + session::disconnect("protocol.entity_id_desync"); + spdlog::critical("receive: entity desync: network {} resolved as client {}", static_cast(entity), + static_cast(created)); + + message_box::reset(); + message_box::set_title("disconnected.disconnected"); + message_box::set_subtitle("protocol.entity_id_desync"); + message_box::add_button("disconnected.back", [](void) { + globals::gui_screen = GUI_PLAY_MENU; + window_title::update(); + }); + + globals::gui_screen = GUI_MESSAGE_BOX; + + return false; +} + +static void on_dimension_info_packet(const protocol::DimensionInfo& packet) +{ + if(session::peer) { + if(globals::dimension) { + delete globals::dimension; + globals::dimension = nullptr; + globals::player = entt::null; + } + + globals::dimension = new Dimension(packet.name.c_str(), packet.gravity); + } +} + +static void on_chunk_voxels_packet(const protocol::ChunkVoxels& packet) +{ + if(session::peer && globals::dimension) { + auto chunk = globals::dimension->create_chunk(packet.chunk); + chunk->set_voxels(packet.voxels); + + ChunkUpdateEvent event; + event.dimension = globals::dimension; + event.cpos = packet.chunk; + event.chunk = chunk; + + globals::dispatcher.trigger(event); + + return; + } +} + +static void on_entity_head_packet(const protocol::EntityHead& packet) +{ + if(session::peer && globals::dimension) { + if(synchronize_entity_id(globals::dimension, packet.entity)) { + auto& component = globals::dimension->entities.get_or_emplace(packet.entity); + auto& prevcomp = globals::dimension->entities.get_or_emplace(packet.entity); + + // Store the previous component state + prevcomp.angles = component.angles; + prevcomp.offset = component.offset; + + // Assign the new component state + component.angles = packet.angles; + } + } +} + +static void on_entity_transform_packet(const protocol::EntityTransform& packet) +{ + if(session::peer && globals::dimension) { + if(synchronize_entity_id(globals::dimension, packet.entity)) { + auto& component = globals::dimension->entities.get_or_emplace(packet.entity); + auto& prevcomp = globals::dimension->entities.get_or_emplace(packet.entity); + + // Store the previous component state + prevcomp.angles = component.angles; + prevcomp.chunk = component.chunk; + prevcomp.local = component.local; + + // Assign the new component state + component.angles = packet.angles; + component.chunk = packet.chunk; + component.local = packet.local; + } + } +} + +static void on_entity_velocity_packet(const protocol::EntityVelocity& packet) +{ + if(session::peer && globals::dimension) { + if(synchronize_entity_id(globals::dimension, packet.entity)) { + auto& component = globals::dimension->entities.get_or_emplace(packet.entity); + component.value = packet.value; + } + } +} + +static void on_entity_player_packet(const protocol::EntityPlayer& packet) +{ + if(session::peer && globals::dimension) { + if(synchronize_entity_id(globals::dimension, packet.entity)) { + client_factory::create_player(globals::dimension, packet.entity); + } + } +} + +static void on_spawn_player_packet(const protocol::SpawnPlayer& packet) +{ + if(session::peer && globals::dimension) { + if(synchronize_entity_id(globals::dimension, packet.entity)) { + client_factory::create_player(globals::dimension, packet.entity); + + globals::player = packet.entity; + globals::gui_screen = GUI_SCREEN_NONE; + + client_chat::refresh_timings(); + + window_title::update(); + } + } +} + +static void on_remove_entity_packet(const protocol::RemoveEntity& packet) +{ + if(globals::dimension) { + if(packet.entity == globals::player) { + globals::player = entt::null; + } + + globals::dimension->entities.destroy(packet.entity); + } +} + +static void on_generic_sound_packet(const protocol::GenericSound& packet) +{ + sound::play_generic(packet.sound.c_str(), packet.looping, packet.pitch); +} + +static void on_entity_sound_packet(const protocol::EntitySound& packet) +{ + sound::play_entity(packet.entity, packet.sound.c_str(), packet.looping, packet.pitch); +} + +void client_receive::init(void) +{ + globals::dispatcher.sink().connect<&on_dimension_info_packet>(); + globals::dispatcher.sink().connect<&on_chunk_voxels_packet>(); + globals::dispatcher.sink().connect<&on_entity_head_packet>(); + globals::dispatcher.sink().connect<&on_entity_transform_packet>(); + globals::dispatcher.sink().connect<&on_entity_velocity_packet>(); + globals::dispatcher.sink().connect<&on_entity_player_packet>(); + globals::dispatcher.sink().connect<&on_spawn_player_packet>(); + globals::dispatcher.sink().connect<&on_remove_entity_packet>(); + globals::dispatcher.sink().connect<&on_generic_sound_packet>(); + globals::dispatcher.sink().connect<&on_entity_sound_packet>(); +} -- cgit