DeerithEngine/deerith_engine_server/src/world/player_communication.cpp

120 lines
3.8 KiB
C++

#include <deerith/engine.h>
#include <deerith/world.h>
#include <deerith/world/components.h>
#include <deerith/network/packets.h>
#include <deerith/network/router.h>
#include <deerith/network/client.h>
#include <deerith/network/network_internals.h>
#include <deerith/world/world_internals.h>
namespace deerith
{
}
void deerith::load_base_protocols()
{
router_add_packet_processor<packet_update_player_input_t>();
}
template <>
void deerith::process_packet(packet_update_player_input_t &packet, client_t *client)
{
entity_t entity = client->entity_id;
component_player_sync_input_t &sync_client = get_component<component_player_sync_input_t>(entity);
packet.input_transport.recive(sync_client.move_input);
packet.position_transport.recive(sync_client.position);
}
void deerith::client_connects(client_t *client)
{
// sync world tick
packet_sync_world_tick_t sync_world_tick;
sync_world_tick.tick_id = get_world_tick();
router_send_packet(sync_world_tick, client);
// create entity player entity
entity_t entity = create_entity();
component_player_sync_input_t &position_sync = add_component<component_player_sync_input_t>(entity);
packet_create_player_entity_t create_player_entity;
router_send_packet(create_player_entity, client);
// create the server representation of the entity
add_entity_network_id(entity);
add_component<component_sync_coordinates_t>(entity);
send_create_entity_to_all_clients(entity);
// we do this the last to avoid send_create_entity_to_all_clients send_create_actual_entities_to_client create the same entity for the player
component_client_link_t &link = add_component<component_client_link_t>(entity);
client->entity_id = entity;
link.client = client;
send_create_actual_entities_to_client(client);
}
void deerith::send_create_entity_to_all_clients(deerith::entity_t ent)
{
auto view = get_entity_registry().view<component_client_link_t>();
for (auto [entity, link_to_client] : view.each())
{
send_create_entity_to_client(ent, link_to_client.client);
}
}
void deerith::send_create_entity_to_client(entity_t ent, client_t *client)
{
component_network_id_t &entity_network_id = get_component<component_network_id_t>(ent);
packet_create_entity_t create_entity;
create_entity.network_sync_id = entity_network_id.network_id;
// in case its the self entity we let it know to the client
if (has_component<component_client_link_t>(ent))
{
component_client_link_t &link = get_component<component_client_link_t>(ent);
create_entity.is_self_client = link.client == client;
deerith_trace("entity could be self {}", create_entity.is_self_client);
}
if (has_component<component_sync_coordinates_t>(ent))
{
create_entity.add_entity_sync_coordinates = true;
}
router_send_packet(create_entity, client);
}
void deerith::client_disconnects(client_t *client)
{
entity_t client_entity = client->entity_id;
send_delete_entity_to_all_clients(client_entity);
get_entity_registry().destroy(client_entity);
}
void deerith::send_delete_entity_to_all_clients(entity_t ent)
{
packet_destroy_entity_t destroy_entity;
component_network_id_t &network_id = get_component<component_network_id_t>(ent);
destroy_entity.network_sync_id = network_id.network_id;
auto view = get_entity_registry().view<component_client_link_t>();
for (auto [entity, link_to_client] : view.each())
{
router_send_packet(destroy_entity, link_to_client.client);
}
}
void deerith::send_create_actual_entities_to_client(client_t *client)
{
auto entities_view = get_entity_registry().view<component_network_id_t>();
for (auto [ent, network_id] : entities_view.each())
{
send_create_entity_to_client(ent, client);
}
}