world: send data only to active viewers

isolation_bkp/dynres
Dominik Madarász 2022-07-31 14:21:40 +02:00
parent 5fe4ed2ee8
commit ffb8aa80a2
10 changed files with 102 additions and 19 deletions

View File

@ -21,6 +21,7 @@
#include "packets/pkt_00_init.h"
#include "packets/pkt_01_welcome.h"
#include "packets/pkt_switch_viewer.h"
static uint8_t game_mode;
static uint8_t game_should_close;
@ -43,7 +44,7 @@ static WORLD_PKT_READER(pkt_reader) {
static WORLD_PKT_WRITER(sp_pkt_writer) {
(void)udata;
return world_read(pkt->data, pkt->datalen, (void*)game_world_view_get_active()->owner_id);
return world_read(pkt->data, pkt->datalen, 0);
}
static WORLD_PKT_WRITER(mp_pkt_writer) {
@ -108,6 +109,7 @@ entity_view *game_world_view_active_get_entity(uint64_t ent_id) {
void game_world_view_set_active(world_view *view) {
active_viewer = view;
camera_set_follow(view->owner_id);
pkt_switch_viewer_send(view->view_id);
}
size_t game_world_view_count(void) {
@ -224,6 +226,7 @@ void game_input() {
}
void game_update() {
static double last_update = 0.0f;
if (game_mode == GAMEKIND_CLIENT) {
network_client_tick();
}
@ -232,8 +235,16 @@ void game_update() {
if (game_mode == GAMEKIND_HEADLESS) {
network_server_tick();
static uint64_t ms_report = 2500;
if (ms_report < zpl_time_rel_ms()) {
ms_report = zpl_time_rel_ms() + 5000;
zpl_printf("delta: %f ms.\n", (zpl_time_rel() - last_update)*1000.0f);
}
}
}
last_update = zpl_time_rel();
}
void game_render() {

View File

@ -24,7 +24,6 @@ static ENetHost *host = NULL;
static ENetHost *server = NULL;
static ENetPeer *peer = NULL;
static librg_world *world = NULL;
static ecs_query_t *clientinfo_query = NULL;
int32_t network_init() {
return enet_initialize() != 0;
@ -180,7 +179,6 @@ int32_t network_server_start(const char *host, uint16_t port) {
return 1;
}
clientinfo_query = ecs_query_new(world_ecs(), "components.ClientInfo");
return 0;
}
@ -220,7 +218,7 @@ int32_t network_server_tick(void) {
}
void network_server_despawn_viewers(void *peer_id) {
ecs_iter_t it = ecs_query_iter(clientinfo_query);
ecs_iter_t it = ecs_query_iter(world_ecs_clientinfo());
while (ecs_query_next(&it)) {
ClientInfo *p = ecs_column(&it, ClientInfo, 1);
@ -234,11 +232,7 @@ void network_server_despawn_viewers(void *peer_id) {
}
uint64_t network_server_get_entity(void *peer_id, uint16_t view_id) {
if (game_get_kind() == GAMEKIND_SINGLE) {
return (uint64_t)peer_id;
}
ecs_iter_t it = ecs_query_iter(clientinfo_query);
ecs_iter_t it = ecs_query_iter(world_ecs_clientinfo());
while (ecs_query_next(&it)) {
ClientInfo *p = ecs_column(&it, ClientInfo, 1);

View File

@ -8,6 +8,7 @@
#include "packets/pkt_01_welcome.h"
#include "packets/pkt_send_keystate.h"
#include "packets/pkt_send_librg_update.h"
#include "packets/pkt_switch_viewer.h"
#define PKT_HEADER_ELEMENTS 3
@ -16,6 +17,7 @@ pkt_handler pkt_handlers[] = {
{.id = MSG_ID_01_WELCOME, .handler = pkt_01_welcome_handler},
{.id = MSG_ID_LIBRG_UPDATE, .handler = pkt_send_librg_update_handler},
{.id = MSG_ID_SEND_KEYSTATE, .handler = pkt_send_keystate_handler},
{.id = MSG_ID_SWITCH_VIEWER, .handler = pkt_switch_viewer_handler},
};
uint8_t pkt_buffer[PKT_BUFSIZ];
@ -190,4 +192,4 @@ void pkt_dump_struct(pkt_desc *desc, void* raw_blob, uint32_t blob_size) {
}
}
zpl_printf("}\n");
}
}

View File

@ -8,6 +8,7 @@ typedef enum {
MSG_ID_01_WELCOME,
MSG_ID_LIBRG_UPDATE,
MSG_ID_SEND_KEYSTATE,
MSG_ID_SWITCH_VIEWER,
MSG_ID_FORCE_UINT16 = UINT16_MAX,
} pkt_messages;

View File

@ -24,19 +24,22 @@ size_t pkt_00_init_send(uint16_t view_id) {
int32_t pkt_00_init_handler(pkt_header *header) {
pkt_00_init table;
PKT_IF(pkt_msg_decode(header, pkt_00_init_desc, pkt_pack_desc_args(pkt_00_init_desc), PKT_STRUCT_PTR(&table)));
uint64_t peer_id = (uint64_t)header->udata;
uint64_t ent_id = player_spawn(NULL);
Position *pos = ecs_get_mut(world_ecs(), ent_id, Position, NULL);
#if 0
pos->x = world_dim()/2.0f + rand()%15*15.0f;
pos->y = world_dim()/2.0f + rand()%15*15.0f;
if (game_get_kind() == GAMEKIND_SINGLE) peer_id = ent_id;
#else
pos->x = rand()%world_dim();
pos->y = rand()%world_dim();
#endif
zpl_printf("[INFO] initializing player entity id: %d with view id: %d for peer id: %d...\n", ent_id, table.view_id, peer_id);
ecs_set(world_ecs(), ent_id, ClientInfo, {.peer = peer_id, .view_id = header->view_id });
ecs_set(world_ecs(), ent_id, ClientInfo, {.peer = peer_id, .view_id = header->view_id, .active = false });
pkt_01_welcome_send(world_seed(), peer_id, header->view_id, ent_id, world_chunk_size(), world_chunk_amount());
return 0;
}

View File

@ -0,0 +1,48 @@
#include "packets/pkt_switch_viewer.h"
#include "packet.h"
#include "world/world.h"
#include "game.h"
#include "network.h"
#include "entity_view.h"
#include "camera.h"
#include "player.h"
#include "modules/components.h"
#include "modules/systems.h"
pkt_desc pkt_switch_viewer_desc[] = {
{ PKT_FIELD(CWP_ITEM_POSITIVE_INTEGER, pkt_switch_viewer, view_id) },
{ PKT_END },
};
size_t pkt_switch_viewer_send(uint16_t view_id) {
pkt_switch_viewer table = {.view_id = view_id };
return pkt_world_write(MSG_ID_SWITCH_VIEWER, pkt_table_encode(pkt_switch_viewer_desc, PKT_STRUCT_PTR(&table)), 1, view_id, NULL, 1);
}
int32_t pkt_switch_viewer_handler(pkt_header *header) {
pkt_switch_viewer table;
PKT_IF(pkt_msg_decode(header, pkt_switch_viewer_desc, pkt_pack_desc_args(pkt_switch_viewer_desc), PKT_STRUCT_PTR(&table)));
ecs_entity_t e = network_server_get_entity(header->udata, header->view_id);
uint64_t peer_id = (uint64_t)header->udata;
if (!world_entity_valid(e))
return 1;
ecs_iter_t it = ecs_query_iter(world_ecs_clientinfo());
while (ecs_query_next(&it)) {
ClientInfo *p = ecs_column(&it, ClientInfo, 1);
for (int i = 0; i < it.count; i++) {
if (p[i].peer == (uintptr_t)peer_id && p[i].view_id == table.view_id) {
p[i].active = true;
} else if (p[i].peer == (uintptr_t)peer_id) {
p[i].active = false;
}
}
}
return 0;
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "system.h"
#include "packet_utils.h"
typedef struct {
uint16_t view_id;
} pkt_switch_viewer;
size_t pkt_switch_viewer_send(uint16_t view_id);
extern pkt_desc pkt_switch_viewer_desc[];
PKT_HANDLER_PROC(pkt_switch_viewer_handler);

View File

@ -203,6 +203,7 @@ void world_setup_ecs(void) {
ECS_IMPORT(world.ecs, Components);
ECS_IMPORT(world.ecs, Systems);
world.ecs_update = ecs_query_new(world.ecs, "components.ClientInfo, components.Position");
world.ecs_clientinfo = ecs_query_new(world.ecs, "components.ClientInfo");
}
static inline
@ -289,6 +290,9 @@ static void world_tracker_update(uint8_t ticker, float freq, uint8_t radius) {
for (int i = 0; i < it.count; i++) {
size_t datalen = WORLD_LIBRG_BUFSIZ;
if (!p[i].active)
continue;
int32_t result = librg_world_write(world_tracker(), it.entities[i], radius, buffer, &datalen, NULL);
if (result > 0) {
@ -366,6 +370,10 @@ ecs_world_t * world_ecs() {
return world.ecs;
}
ecs_query_t *world_ecs_clientinfo(void) {
return world.ecs_clientinfo;
}
void world_set_stage(ecs_world_t *ecs) {
world.ecs_stage = ecs;
}

View File

@ -46,6 +46,7 @@ typedef struct {
ecs_world_t *ecs;
ecs_world_t *ecs_stage;
ecs_query_t *ecs_update;
ecs_query_t *ecs_clientinfo;
ecs_entity_t *chunk_mapping;
librg_world *tracker;
world_pkt_reader_proc *reader_proc;
@ -63,6 +64,7 @@ int32_t world_write(pkt_header *pkt, void *udata);
uint32_t world_buf(block_id const **ptr, uint32_t *width);
uint32_t world_seed(void);
ecs_world_t *world_ecs(void);
ecs_query_t *world_ecs_clientinfo(void);
void world_set_stage(ecs_world_t *ecs);
librg_world *world_tracker(void);
@ -113,4 +115,4 @@ int64_t *world_chunk_fetch_entities(librg_chunk chunk_id, size_t *ents_len);
int64_t *world_chunk_fetch_entities_realpos(float x, float y, size_t *ents_len);
int64_t *world_chunk_query_entities(int64_t e, size_t *ents_len, int8_t radius);
bool world_entity_valid(ecs_entity_t e);
bool world_entity_valid(ecs_entity_t e);

View File

@ -61,7 +61,8 @@ ECS_STRUCT(Input, {
ECS_STRUCT(ClientInfo, {
uintptr_t peer;
uint16_t view_id;
uint16_t view_id;
uint8_t active;
});
ECS_STRUCT(Health, {