diff --git a/code/game/src/game.c b/code/game/src/game.c index 50da9b8..9a69d4d 100644 --- a/code/game/src/game.c +++ b/code/game/src/game.c @@ -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() { diff --git a/code/game/src/network.c b/code/game/src/network.c index ad7a8c1..5a62ff0 100644 --- a/code/game/src/network.c +++ b/code/game/src/network.c @@ -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); diff --git a/code/game/src/packet.c b/code/game/src/packet.c index e14166d..01d2530 100644 --- a/code/game/src/packet.c +++ b/code/game/src/packet.c @@ -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"); -} \ No newline at end of file +} diff --git a/code/game/src/packet.h b/code/game/src/packet.h index 18e6762..a2dd185 100644 --- a/code/game/src/packet.h +++ b/code/game/src/packet.h @@ -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; diff --git a/code/game/src/packets/pkt_00_init.c b/code/game/src/packets/pkt_00_init.c index 52c55cd..0c5fbe8 100644 --- a/code/game/src/packets/pkt_00_init.c +++ b/code/game/src/packets/pkt_00_init.c @@ -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; } diff --git a/code/game/src/packets/pkt_switch_viewer.c b/code/game/src/packets/pkt_switch_viewer.c new file mode 100644 index 0000000..d5f7884 --- /dev/null +++ b/code/game/src/packets/pkt_switch_viewer.c @@ -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; +} diff --git a/code/game/src/packets/pkt_switch_viewer.h b/code/game/src/packets/pkt_switch_viewer.h new file mode 100644 index 0000000..3312405 --- /dev/null +++ b/code/game/src/packets/pkt_switch_viewer.h @@ -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); + diff --git a/code/game/src/world/world.c b/code/game/src/world/world.c index b18624d..0e54288 100644 --- a/code/game/src/world/world.c +++ b/code/game/src/world/world.c @@ -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; } diff --git a/code/game/src/world/world.h b/code/game/src/world/world.h index f4ba77b..a8edb14 100644 --- a/code/game/src/world/world.h +++ b/code/game/src/world/world.h @@ -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); \ No newline at end of file +bool world_entity_valid(ecs_entity_t e); diff --git a/code/modules/modules/components.h b/code/modules/modules/components.h index 648ecec..1d79cfd 100644 --- a/code/modules/modules/components.h +++ b/code/modules/modules/components.h @@ -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, {