refactor the world system
parent
8c122607a8
commit
97b4cc6864
|
@ -19,5 +19,5 @@ add_subdirectory(code/common)
|
|||
add_subdirectory(code/vendors)
|
||||
|
||||
add_subdirectory(code/apps/client)
|
||||
add_subdirectory(code/apps/server)
|
||||
add_subdirectory(code/apps/playground)
|
||||
#add_subdirectory(code/apps/server)
|
||||
#add_subdirectory(code/apps/playground)
|
||||
|
|
|
@ -7,6 +7,7 @@ add_library(client-common STATIC
|
|||
source/main.c
|
||||
source/camera.c
|
||||
source/entity_view.c
|
||||
source/world_view.c
|
||||
|
||||
source/utils/options.c
|
||||
|
||||
|
|
|
@ -11,11 +11,11 @@ typedef struct entity_view {
|
|||
|
||||
ZPL_TABLE_DECLARE(, entity_view_tbl, entity_view_tbl_, entity_view);
|
||||
|
||||
void entity_view_init(void);
|
||||
void entity_view_free(void);
|
||||
void entity_view_init(entity_view_tbl *map);
|
||||
void entity_view_free(entity_view_tbl *map);
|
||||
|
||||
void entity_view_update_or_create(uint64_t ent_id, entity_view data);
|
||||
void entity_view_destroy(uint64_t ent_id);
|
||||
void entity_view_update_or_create(entity_view_tbl *map, uint64_t ent_id, entity_view data);
|
||||
void entity_view_destroy(entity_view_tbl *map, uint64_t ent_id);
|
||||
|
||||
entity_view *entity_view_get(uint64_t ent_id);
|
||||
void entity_view_map(void (*map_proc)(uint64_t key, entity_view value));
|
||||
entity_view *entity_view_get(entity_view_tbl *map, uint64_t ent_id);
|
||||
void entity_view_map(entity_view_tbl *map, void (*map_proc)(uint64_t key, entity_view value));
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
#include "system.h"
|
||||
#include "entity_view.h"
|
||||
#include "world/world.h"
|
||||
|
||||
typedef struct {
|
||||
uint64_t owner_id;
|
||||
entity_view_tbl entities;
|
||||
librg_world *tracker;
|
||||
} world_view;
|
||||
|
||||
world_view world_view_create(void);
|
||||
void world_view_init(world_view *view, uint64_t ent_id, uint16_t block_size, uint16_t chunk_size, uint16_t world_size);
|
||||
void world_view_destroy(world_view *view);
|
|
@ -1,6 +1,7 @@
|
|||
#include "zpl.h"
|
||||
#include "camera.h"
|
||||
#include "entity_view.h"
|
||||
#include "game.h"
|
||||
|
||||
static camera main_camera;
|
||||
|
||||
|
@ -12,7 +13,7 @@ void camera_reset(void) {
|
|||
void camera_update(void) {
|
||||
switch (main_camera.mode) {
|
||||
case CAMERA_MODE_FOLLOW: {
|
||||
entity_view *view = entity_view_get(main_camera.ent_id);
|
||||
entity_view *view = entity_view_get(game_world_view_get_active(), main_camera.ent_id);
|
||||
if (!view) break;
|
||||
|
||||
main_camera.x = view->x;
|
||||
|
|
|
@ -2,29 +2,26 @@
|
|||
|
||||
ZPL_TABLE_DEFINE(entity_view_tbl, entity_view_tbl_, entity_view);
|
||||
|
||||
static entity_view_tbl cli_entities = {0};
|
||||
|
||||
|
||||
void entity_view_init(void) {
|
||||
entity_view_tbl_init(&cli_entities, zpl_heap());
|
||||
void entity_view_init(entity_view_tbl *map) {
|
||||
entity_view_tbl_init(map, zpl_heap());
|
||||
}
|
||||
|
||||
void entity_view_free(void) {
|
||||
entity_view_tbl_destroy(&cli_entities);
|
||||
void entity_view_free(entity_view_tbl *map) {
|
||||
entity_view_tbl_destroy(map);
|
||||
}
|
||||
|
||||
void entity_view_update_or_create(uint64_t ent_id, entity_view data) {
|
||||
entity_view_tbl_set(&cli_entities, ent_id, data);
|
||||
void entity_view_update_or_create(entity_view_tbl *map, uint64_t ent_id, entity_view data) {
|
||||
entity_view_tbl_set(map, ent_id, data);
|
||||
}
|
||||
|
||||
void entity_view_destroy(uint64_t ent_id) {
|
||||
entity_view_tbl_remove(&cli_entities, ent_id);
|
||||
void entity_view_destroy(entity_view_tbl *map, uint64_t ent_id) {
|
||||
entity_view_tbl_remove(map, ent_id);
|
||||
}
|
||||
|
||||
entity_view *entity_view_get(uint64_t ent_id) {
|
||||
return entity_view_tbl_get(&cli_entities, ent_id);
|
||||
entity_view *entity_view_get(entity_view_tbl *map, uint64_t ent_id) {
|
||||
return entity_view_tbl_get(map, ent_id);
|
||||
}
|
||||
|
||||
void entity_view_map(void (*map_proc)(uint64_t key, entity_view value)) {
|
||||
entity_view_tbl_map(&cli_entities, map_proc);
|
||||
void entity_view_map(entity_view_tbl *map, void (*map_proc)(uint64_t key, entity_view value)) {
|
||||
entity_view_tbl_map(map, map_proc);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
#include "game.h"
|
||||
#include "zpl.h"
|
||||
#include "platform.h"
|
||||
#include "world/world.h"
|
||||
#include "packet.h"
|
||||
#include "signal_handling.h"
|
||||
#include "network.h"
|
||||
#include "world_view.h"
|
||||
#include "entity_view.h"
|
||||
#include "camera.h"
|
||||
|
||||
|
@ -12,14 +14,18 @@
|
|||
#include "flecs/flecs_systems_civetweb.h"
|
||||
#include "flecs/flecs_os_api_stdcpp.h"
|
||||
|
||||
#include "packets/pkt_00_init.h"
|
||||
#include "packets/pkt_01_welcome.h"
|
||||
|
||||
static int8_t is_networked_play;
|
||||
static uint64_t sp_player;
|
||||
|
||||
static world_view *world_viewers;
|
||||
static world_view *active_viewer;
|
||||
|
||||
static WORLD_PKT_READER(pkt_reader) {
|
||||
pkt_header header = {0};
|
||||
uint32_t ok = pkt_header_decode(&header, data, datalen);
|
||||
header.udata = udata;
|
||||
|
||||
if (ok && header.ok) {
|
||||
return pkt_handlers[header.id].handler(&header) >= 0;
|
||||
|
@ -30,7 +36,7 @@ static WORLD_PKT_READER(pkt_reader) {
|
|||
}
|
||||
|
||||
static WORLD_PKT_WRITER(sp_pkt_writer) {
|
||||
return world_read(pkt->data, pkt->datalen, NULL);
|
||||
return world_read(pkt->data, pkt->datalen, 0);
|
||||
}
|
||||
|
||||
static WORLD_PKT_WRITER(mp_pkt_writer) {
|
||||
|
@ -42,33 +48,57 @@ static WORLD_PKT_WRITER(mp_pkt_writer) {
|
|||
}
|
||||
}
|
||||
|
||||
void game_init(int8_t play_mode, int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size) {
|
||||
void world_viewers_init(uint32_t num_viewers) {
|
||||
zpl_buffer_init(world_viewers, zpl_heap(), num_viewers);
|
||||
|
||||
for (uint32_t i = 0; i < num_viewers; i++) {
|
||||
world_viewers[i] = world_view_create();
|
||||
}
|
||||
}
|
||||
|
||||
void world_viewers_destroy() {
|
||||
for (uint32_t i = 0; i < zpl_buffer_count(world_viewers); i++) {
|
||||
world_view_destroy(&world_viewers[i]);
|
||||
}
|
||||
zpl_buffer_free(world_viewers);
|
||||
}
|
||||
|
||||
world_view *game_world_view_get(uint16_t idx) {
|
||||
return &world_viewers[idx];
|
||||
}
|
||||
|
||||
world_view *game_world_view_get_active(void) {
|
||||
return active_viewer;
|
||||
}
|
||||
|
||||
void flecs_dash_init() {
|
||||
ECS_IMPORT(world_ecs(), FlecsDash);
|
||||
ECS_IMPORT(world_ecs(), FlecsSystemsCivetweb);
|
||||
|
||||
ecs_set(world_ecs(), 0, EcsDashServer, {.port = 27001});
|
||||
ecs_set_target_fps(world_ecs(), 60);
|
||||
}
|
||||
|
||||
void game_init(int8_t play_mode, uint32_t num_viewers, int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size) {
|
||||
is_networked_play = play_mode;
|
||||
platform_init();
|
||||
entity_view_init();
|
||||
world_viewers_init(num_viewers);
|
||||
active_viewer = &world_viewers[0];
|
||||
camera_reset();
|
||||
|
||||
if (is_networked_play) {
|
||||
world_init_minimal(0, 0, 0, pkt_reader, mp_pkt_writer);
|
||||
world_setup_pkt_handlers(pkt_reader, mp_pkt_writer);
|
||||
network_init();
|
||||
network_client_connect("127.0.0.1", 27000);
|
||||
} else {
|
||||
stdcpp_set_os_api();
|
||||
world_init(seed, block_size, chunk_size, world_size, pkt_reader, sp_pkt_writer);
|
||||
|
||||
/* server dashboard */
|
||||
{
|
||||
ECS_IMPORT(world_ecs(), FlecsDash);
|
||||
ECS_IMPORT(world_ecs(), FlecsSystemsCivetweb);
|
||||
|
||||
ecs_set(world_ecs(), 0, EcsDashServer, {.port = 27001});
|
||||
ecs_set_target_fps(world_ecs(), 60);
|
||||
}
|
||||
|
||||
sp_player = player_spawn("unnamed");
|
||||
|
||||
pkt_01_welcome table = {.ent_id = 0, .block_size = block_size, .chunk_size = chunk_size, .world_size = world_size};
|
||||
pkt_world_write(MSG_ID_01_WELCOME, pkt_01_welcome_encode(&table), 1, NULL);
|
||||
world_setup_pkt_handlers(pkt_reader, sp_pkt_writer);
|
||||
world_init(seed, block_size, chunk_size, world_size);
|
||||
flecs_dash_init();
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < num_viewers; i++) {
|
||||
pkt_00_init_send(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,13 +107,12 @@ int8_t game_is_networked() {
|
|||
}
|
||||
|
||||
void game_shutdown() {
|
||||
entity_view_free();
|
||||
world_viewers_destroy();
|
||||
|
||||
if (is_networked_play) {
|
||||
network_client_disconnect();
|
||||
network_destroy();
|
||||
} else {
|
||||
player_despawn(sp_player);
|
||||
world_destroy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ int main(int argc, char** argv)
|
|||
|
||||
zpl_opts_add(&opts, "?", "help", "the HELP section", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "s", "single-player", "play single-player game.", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "c", "viewer-count", "number of viewers (detachable clients)", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "p", "preview-map", "draw world preview", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "s", "seed", "world seed", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "r", "random-seed", "generate random world seed", ZPL_OPTS_FLAG);
|
||||
|
@ -33,6 +34,7 @@ int main(int argc, char** argv)
|
|||
|
||||
int8_t is_networked_play = !zpl_opts_has_arg(&opts, "single-player");
|
||||
int32_t seed = zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED);
|
||||
uint16_t num_viewers = zpl_opts_integer(&opts, "viewer-count", 1);
|
||||
uint16_t block_size = zpl_opts_integer(&opts, "block-size", DEFAULT_BLOCK_SIZE);
|
||||
uint16_t chunk_size = zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE);
|
||||
uint16_t world_size = zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE);
|
||||
|
@ -50,7 +52,7 @@ int main(int argc, char** argv)
|
|||
}
|
||||
|
||||
sighandler_register();
|
||||
game_init(is_networked_play, seed, block_size, chunk_size, world_size);
|
||||
game_init(is_networked_play, num_viewers, seed, block_size, chunk_size, world_size);
|
||||
|
||||
while (game_is_running()) {
|
||||
game_input();
|
||||
|
|
|
@ -26,6 +26,7 @@ int32_t network_destroy() {
|
|||
|
||||
}
|
||||
|
||||
|
||||
int32_t network_client_connect(const char *hostname, uint16_t port) {
|
||||
ENetAddress address = {0}; address.port = port;
|
||||
enet_address_set_host(&address, hostname);
|
||||
|
|
|
@ -40,7 +40,7 @@ void platform_render() {
|
|||
ClearBackground(BLACK);
|
||||
BeginMode2D(render_camera);
|
||||
DrawRectangleV((Vector2){0,0}, (Vector2){40,40}, RED);
|
||||
entity_view_map(DEBUG_draw_entities);
|
||||
entity_view_map(&game_world_view_get_active()->entities, DEBUG_draw_entities);
|
||||
EndMode2D();
|
||||
display_conn_status();
|
||||
EndDrawing();
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
#include "world_view.h"
|
||||
#include "librg.h"
|
||||
|
||||
int32_t tracker_read_create(librg_world *w, librg_event *e) {
|
||||
int64_t owner_id = librg_event_owner_get(w, e);
|
||||
int64_t entity_id = librg_event_entity_get(w, e);
|
||||
zpl_printf("[INFO] An entity %d was created for owner: %d\n", (int)entity_id, (int)owner_id);
|
||||
world_view *view = (world_view*)librg_world_userdata_get(w);
|
||||
|
||||
// TODO(zaklaus): receive real data
|
||||
entity_view_update_or_create(&view->entities, entity_id, (entity_view){0});
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tracker_read_remove(librg_world *w, librg_event *e) {
|
||||
int64_t owner_id = librg_event_owner_get(w, e);
|
||||
int64_t entity_id = librg_event_entity_get(w, e);
|
||||
zpl_printf("[INFO] An entity %d was removed for owner: %d\n", (int)entity_id, (int)owner_id);
|
||||
world_view *view = (world_view*)librg_world_userdata_get(w);
|
||||
|
||||
entity_view_destroy(&view->entities, entity_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tracker_read_update(librg_world *w, librg_event *e) {
|
||||
// int64_t entity_id = librg_event_entity_get(w, e);
|
||||
size_t actual_length = librg_event_size_get(w, e);
|
||||
char *buffer = librg_event_buffer_get(w, e);
|
||||
|
||||
// TODO(zaklaus): update real data
|
||||
return 0;
|
||||
}
|
||||
|
||||
world_view world_view_create(void) {
|
||||
world_view view = {0};
|
||||
view.tracker = librg_world_create();
|
||||
entity_view_init(&view.entities);
|
||||
return view;
|
||||
}
|
||||
|
||||
void world_view_init(world_view *view, uint64_t ent_id, uint16_t block_size, uint16_t chunk_size, uint16_t world_size) {
|
||||
view->owner_id = ent_id;
|
||||
librg_config_chunksize_set(view->tracker, block_size * chunk_size, block_size * chunk_size, 1);
|
||||
librg_config_chunkamount_set(view->tracker, world_size, world_size, 1);
|
||||
librg_config_chunkoffset_set(view->tracker, LIBRG_OFFSET_MID, LIBRG_OFFSET_MID, 0);
|
||||
|
||||
librg_event_set(view->tracker, LIBRG_READ_CREATE, tracker_read_create);
|
||||
librg_event_set(view->tracker, LIBRG_READ_REMOVE, tracker_read_remove);
|
||||
librg_event_set(view->tracker, LIBRG_READ_UPDATE, tracker_read_update);
|
||||
librg_world_userdata_set(view->tracker, view);
|
||||
}
|
||||
|
||||
void world_view_destroy(world_view *view) {
|
||||
librg_world_destroy(view->tracker);
|
||||
entity_view_free(&view->entities);
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
#include "system.h"
|
||||
#include "world_view.h"
|
||||
|
||||
void game_init(int8_t play_mode, int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size);
|
||||
void game_init(int8_t play_mode, uint32_t num_viewers, int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size);
|
||||
void game_shutdown();
|
||||
uint8_t game_is_running();
|
||||
int8_t game_is_networked();
|
||||
|
@ -9,3 +10,6 @@ int8_t game_is_networked();
|
|||
void game_input();
|
||||
void game_update();
|
||||
void game_render();
|
||||
|
||||
world_view *game_world_view_get_active(void);
|
||||
world_view *game_world_view_get(uint16_t idx);
|
|
@ -4,23 +4,26 @@
|
|||
|
||||
// NOTE(zaklaus): packets
|
||||
|
||||
#include "packets/pkt_00_init.h"
|
||||
#include "packets/pkt_01_welcome.h"
|
||||
#include "packets/pkt_send_keystate.h"
|
||||
#include "packets/pkt_send_librg_update.h"
|
||||
|
||||
#define PKT_HEADER_ELEMENTS 2
|
||||
#define PKT_HEADER_ELEMENTS 3
|
||||
|
||||
pkt_handler pkt_handlers[] = {
|
||||
{.id = MSG_ID_00_INIT, .handler = pkt_00_init_handler},
|
||||
{.id = MSG_ID_01_WELCOME, .handler = pkt_01_welcome_handler},
|
||||
{.id = MSG_ID_LIBRG_UPDATE, .handler = pkt_send_librg_update_handler},
|
||||
};
|
||||
|
||||
uint8_t pkt_buffer[PKT_BUFSIZ];
|
||||
|
||||
int32_t pkt_header_encode(pkt_messages id, void *data, size_t datalen) {
|
||||
int32_t pkt_header_encode(pkt_messages id, uint16_t view_id, void *data, size_t datalen) {
|
||||
cw_pack_context pc = {0};
|
||||
pkt_pack_msg(&pc, PKT_HEADER_ELEMENTS);
|
||||
cw_pack_unsigned(&pc, id);
|
||||
cw_pack_unsigned(&pc, view_id);
|
||||
cw_pack_bin(&pc, data, datalen);
|
||||
return pkt_pack_msg_size(&pc);
|
||||
}
|
||||
|
@ -35,12 +38,20 @@ int32_t pkt_header_decode(pkt_header *table, void *data, size_t datalen) {
|
|||
}
|
||||
|
||||
uint16_t pkt_id = (uint16_t)uc.item.as.u64;
|
||||
|
||||
|
||||
cw_unpack_next(&uc);
|
||||
if (uc.item.type != CWP_ITEM_POSITIVE_INTEGER || uc.item.as.u64 > UINT16_MAX) {
|
||||
return -1; // invalid view id
|
||||
}
|
||||
|
||||
uint16_t view_id = (uint16_t)uc.item.as.u64;
|
||||
|
||||
cw_unpack_next(&uc);
|
||||
const void *packed_blob = uc.item.as.bin.start;
|
||||
uint32_t packed_size = uc.item.as.bin.length;
|
||||
|
||||
table->id = pkt_id;
|
||||
table->view_id = view_id;
|
||||
table->data = packed_blob;
|
||||
table->datalen = packed_size;
|
||||
table->ok = 1;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#define PKT_BUFSIZ 4096
|
||||
|
||||
typedef enum {
|
||||
MSG_ID_00_INIT,
|
||||
MSG_ID_01_WELCOME,
|
||||
MSG_ID_LIBRG_UPDATE,
|
||||
MSG_ID_SEND_KEYSTATE,
|
||||
|
@ -13,10 +14,12 @@ typedef enum {
|
|||
typedef struct pkt_header {
|
||||
uint16_t id;
|
||||
uint16_t sender;
|
||||
uint16_t view_id;
|
||||
uint8_t *data;
|
||||
uint32_t datalen;
|
||||
int8_t is_reliable;
|
||||
int8_t ok;
|
||||
void* udata;
|
||||
} pkt_header;
|
||||
|
||||
#define PKT_HANDLER_PROC(name) int32_t name(pkt_header *header)
|
||||
|
@ -27,7 +30,7 @@ typedef struct {
|
|||
pkt_handler_proc *handler;
|
||||
} pkt_handler;
|
||||
|
||||
int32_t pkt_header_encode(pkt_messages id, void *data, size_t datalen);
|
||||
int32_t pkt_header_encode(pkt_messages id, uint16_t view_id, void *data, size_t datalen);
|
||||
int32_t pkt_header_decode(pkt_header *table, void *data, size_t datalen);
|
||||
|
||||
extern pkt_handler pkt_handlers[];
|
||||
|
|
|
@ -39,13 +39,14 @@ inline size_t pkt_pack_msg_size(cw_pack_context *pc) {
|
|||
return pc->current - pc->start; // NOTE(zaklaus): length
|
||||
}
|
||||
|
||||
inline int32_t pkt_prep_msg(pkt_header *pkt, pkt_messages id, size_t pkt_size, int8_t is_reliable) {
|
||||
inline int32_t pkt_prep_msg(pkt_header *pkt, pkt_messages id, uint16_t view_id, size_t pkt_size, int8_t is_reliable) {
|
||||
zpl_zero_item(pkt);
|
||||
static uint8_t pkt_data[PKT_BUFSIZ] = {0};
|
||||
zpl_memcopy(pkt_data, pkt_buffer, pkt_size);
|
||||
|
||||
pkt->data = pkt_buffer;
|
||||
pkt->datalen = pkt_header_encode(id, pkt_data, pkt_size);
|
||||
pkt->view_id = view_id;
|
||||
pkt->datalen = pkt_header_encode(id, view_id, pkt_data, pkt_size);
|
||||
pkt->is_reliable = is_reliable;
|
||||
pkt->id = id;
|
||||
return 0;
|
||||
|
@ -53,9 +54,9 @@ inline int32_t pkt_prep_msg(pkt_header *pkt, pkt_messages id, size_t pkt_size, i
|
|||
|
||||
extern int32_t world_write(pkt_header *pkt, void *udata);
|
||||
|
||||
inline int32_t pkt_world_write(pkt_messages id, size_t pkt_size, int8_t is_reliable, void *udata) {
|
||||
inline int32_t pkt_world_write(pkt_messages id, size_t pkt_size, int8_t is_reliable, uint16_t view_id, void *udata) {
|
||||
pkt_header pkt;
|
||||
PKT_IF(pkt_prep_msg(&pkt, id, pkt_size, is_reliable));
|
||||
PKT_IF(pkt_prep_msg(&pkt, id, view_id, pkt_size, is_reliable));
|
||||
return world_write(&pkt, udata);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
#include "packets/pkt_00_init.h"
|
||||
#include "packets/pkt_01_welcome.h"
|
||||
#include "packet.h"
|
||||
#include "world/world.h"
|
||||
#include "game.h"
|
||||
#include "entity_view.h"
|
||||
#include "camera.h"
|
||||
|
||||
#include "modules/net.h"
|
||||
|
||||
pkt_desc pkt_00_init_desc[] = {
|
||||
{ PKT_FIELD(CWP_ITEM_POSITIVE_INTEGER, pkt_00_init, view_id) },
|
||||
{ PKT_END },
|
||||
};
|
||||
|
||||
size_t pkt_00_init_encode(pkt_00_init *table) {
|
||||
cw_pack_context pc = {0};
|
||||
pkt_pack_msg(&pc, pkt_pack_desc_args(pkt_00_init_desc));
|
||||
pkt_pack_struct(&pc, pkt_00_init_desc, PKT_STRUCT_PTR(table));
|
||||
return pkt_pack_msg_size(&pc);
|
||||
}
|
||||
|
||||
size_t pkt_00_init_send(uint16_t view_id) {
|
||||
pkt_00_init table = {.view_id = view_id };
|
||||
return pkt_world_write(MSG_ID_00_INIT, pkt_00_init_encode(&table), 1, view_id, NULL);
|
||||
}
|
||||
|
||||
int32_t pkt_00_init_handler(pkt_header *header) {
|
||||
ECS_IMPORT(world_ecs(), Net);
|
||||
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(zpl_bprintf("client_%d", peer_id));
|
||||
ecs_set(world_ecs(), ent_id, ClientInfo, {.peer = ent_id, .view_id = header->view_id });
|
||||
pkt_01_welcome_send(peer_id, header->view_id, ent_id, world_block_size(), world_chunk_size(), world_world_size());
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
#include "system.h"
|
||||
#include "packet_utils.h"
|
||||
|
||||
typedef struct {
|
||||
uint16_t view_id;
|
||||
} pkt_00_init;
|
||||
|
||||
size_t pkt_00_init_encode(pkt_00_init *table);
|
||||
size_t pkt_00_init_send(uint16_t view_id);
|
||||
pkt_desc pkt_00_init_desc[];
|
||||
|
||||
PKT_HANDLER_PROC(pkt_00_init_handler);
|
||||
|
|
@ -2,11 +2,8 @@
|
|||
#include "packet.h"
|
||||
#include "world/world.h"
|
||||
#include "game.h"
|
||||
|
||||
#ifdef CLIENT
|
||||
#include "entity_view.h"
|
||||
#include "camera.h"
|
||||
#endif
|
||||
|
||||
pkt_desc pkt_01_welcome_desc[] = {
|
||||
{ PKT_FIELD(CWP_ITEM_POSITIVE_INTEGER, pkt_01_welcome, ent_id) },
|
||||
|
@ -22,19 +19,23 @@ size_t pkt_01_welcome_encode(pkt_01_welcome *table) {
|
|||
pkt_pack_struct(&pc, pkt_01_welcome_desc, PKT_STRUCT_PTR(table));
|
||||
return pkt_pack_msg_size(&pc);
|
||||
}
|
||||
size_t pkt_01_welcome_send(uint64_t peer_id,
|
||||
uint16_t view_id,
|
||||
uint64_t ent_id,
|
||||
uint16_t block_size,
|
||||
uint16_t chunk_size,
|
||||
uint16_t world_size) {
|
||||
pkt_01_welcome table = {.ent_id = ent_id, .block_size = block_size, .chunk_size = chunk_size, .world_size = world_size};
|
||||
return pkt_world_write(MSG_ID_01_WELCOME, pkt_01_welcome_encode(&table), 1, view_id, (void*)peer_id);
|
||||
}
|
||||
|
||||
int32_t pkt_01_welcome_handler(pkt_header *header) {
|
||||
pkt_01_welcome table;
|
||||
PKT_IF(pkt_msg_decode(header, pkt_01_welcome_desc, pkt_pack_desc_args(pkt_01_welcome_desc), PKT_STRUCT_PTR(&table)));
|
||||
|
||||
#ifdef CLIENT
|
||||
if (game_is_networked()) {
|
||||
zpl_printf("[INFO] initializing read-only world view ...\n");
|
||||
world_init_minimal(table.block_size, table.chunk_size, table.world_size, NULL, NULL);
|
||||
}
|
||||
|
||||
entity_view_update_or_create(table.ent_id, (entity_view){0});
|
||||
camera_set_follow(table.ent_id);
|
||||
#endif
|
||||
world_view *view = game_world_view_get(header->view_id);
|
||||
|
||||
zpl_printf("[INFO] initializing read-only world view ...\n");
|
||||
world_view_init(view, table.ent_id, table.block_size, table.chunk_size, table.world_size);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,12 @@ typedef struct {
|
|||
uint16_t world_size;
|
||||
} pkt_01_welcome;
|
||||
|
||||
size_t pkt_01_welcome_send(uint64_t peer_id,
|
||||
uint16_t view_id,
|
||||
uint64_t ent_id,
|
||||
uint16_t block_size,
|
||||
uint16_t chunk_size,
|
||||
uint16_t world_size);
|
||||
size_t pkt_01_welcome_encode(pkt_01_welcome *table);
|
||||
pkt_desc pkt_01_welcome_desc[];
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "packet_utils.h"
|
||||
#include "packets/pkt_send_librg_update.h"
|
||||
#include "world/world.h"
|
||||
#include "game.h"
|
||||
|
||||
size_t pkt_send_librg_update_encode(void *data, int32_t data_length) {
|
||||
cw_pack_context pc = {0};
|
||||
|
@ -17,7 +18,9 @@ int32_t pkt_send_librg_update_handler(pkt_header *header) {
|
|||
if (uc.item.type != CWP_ITEM_BIN)
|
||||
return -1;
|
||||
|
||||
int32_t state = librg_world_read(world_tracker(), 1, uc.item.as.bin.start, uc.item.as.bin.length, NULL);
|
||||
world_view *view = game_world_view_get(header->view_id);
|
||||
|
||||
int32_t state = librg_world_read(view->tracker, header->view_id, uc.item.as.bin.start, uc.item.as.bin.length, NULL);
|
||||
if (state < 0) zpl_printf("[ERROR] world read error: %d\n", state);
|
||||
|
||||
return state;
|
||||
|
|
|
@ -29,32 +29,9 @@ static world_data world = {0};
|
|||
|
||||
int32_t world_gen();
|
||||
|
||||
int32_t tracker_read_create(librg_world *w, librg_event *e) {
|
||||
int64_t owner_id = librg_event_owner_get(w, e);
|
||||
int64_t entity_id = librg_event_entity_get(w, e);
|
||||
zpl_printf("[INFO] An entity %d was created for owner: %d\n", (int)entity_id, (int)owner_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tracker_read_remove(librg_world *w, librg_event *e) {
|
||||
int64_t owner_id = librg_event_owner_get(w, e);
|
||||
int64_t entity_id = librg_event_entity_get(w, e);
|
||||
zpl_printf("[INFO] An entity %d was removed for owner: %d\n", (int)entity_id, (int)owner_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tracker_read_update(librg_world *w, librg_event *e) {
|
||||
// int64_t entity_id = librg_event_entity_get(w, e);
|
||||
size_t actual_length = librg_event_size_get(w, e);
|
||||
char *buffer = librg_event_buffer_get(w, e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tracker_write_create(librg_world *w, librg_event *e) {
|
||||
int64_t owner_id = librg_event_owner_get(w, e);
|
||||
int64_t entity_id = librg_event_entity_get(w, e);
|
||||
zpl_printf("let's add prtint here\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -74,11 +51,19 @@ int32_t tracker_write_update(librg_world *w, librg_event *e) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t world_init_minimal(uint16_t block_size, uint16_t chunk_size, uint16_t world_size, world_pkt_reader_proc *reader_proc, world_pkt_writer_proc *writer_proc) {
|
||||
void world_setup_pkt_handlers(world_pkt_reader_proc *reader_proc, world_pkt_writer_proc *writer_proc) {
|
||||
world.reader_proc = reader_proc;
|
||||
world.writer_proc = writer_proc;
|
||||
}
|
||||
|
||||
int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size) {
|
||||
if (world.data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
world.seed = seed;
|
||||
world.chunk_size = chunk_size;
|
||||
world.world_size = world_size;
|
||||
if (reader_proc) world.reader_proc = reader_proc;
|
||||
if (writer_proc) world.writer_proc = writer_proc;
|
||||
|
||||
world.width = chunk_size * world_size;
|
||||
world.height = chunk_size * world_size;
|
||||
|
@ -88,7 +73,7 @@ int32_t world_init_minimal(uint16_t block_size, uint16_t chunk_size, uint16_t wo
|
|||
if (world.tracker == NULL) {
|
||||
world.tracker = librg_world_create();
|
||||
}
|
||||
|
||||
|
||||
if (world.tracker == NULL) {
|
||||
zpl_printf("[ERROR] An error occurred while trying to create a server world.\n");
|
||||
return WORLD_ERROR_TRACKER_FAILED;
|
||||
|
@ -99,24 +84,10 @@ int32_t world_init_minimal(uint16_t block_size, uint16_t chunk_size, uint16_t wo
|
|||
librg_config_chunkamount_set(world.tracker, world_size, world_size, 1);
|
||||
librg_config_chunkoffset_set(world.tracker, LIBRG_OFFSET_MID, LIBRG_OFFSET_MID, 0);
|
||||
|
||||
librg_event_set(world.tracker, LIBRG_READ_CREATE, tracker_read_create);
|
||||
librg_event_set(world.tracker, LIBRG_READ_REMOVE, tracker_read_remove);
|
||||
librg_event_set(world.tracker, LIBRG_READ_UPDATE, tracker_read_update);
|
||||
|
||||
librg_event_set(world.tracker, LIBRG_WRITE_CREATE, tracker_write_create);
|
||||
librg_event_set(world.tracker, LIBRG_WRITE_REMOVE, tracker_write_remove);
|
||||
librg_event_set(world.tracker, LIBRG_WRITE_UPDATE, tracker_write_update);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size, world_pkt_reader_proc *reader_proc, world_pkt_writer_proc *writer_proc) {
|
||||
if (world.data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
world.seed = seed;
|
||||
world_init_minimal(block_size, chunk_size, world_size, reader_proc, writer_proc);
|
||||
world.data = zpl_malloc(sizeof(uint8_t)*world.size);
|
||||
world.tracker_update = 0;
|
||||
|
||||
|
@ -129,11 +100,11 @@ int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint1
|
|||
|
||||
ECS_IMPORT(world.ecs, General);
|
||||
|
||||
for (int i = 0; i < chunk_size * chunk_size; ++i) {
|
||||
for (int i = 0; i < world_size * world_size; ++i) {
|
||||
ecs_entity_t e = ecs_new(world.ecs, 0);
|
||||
ecs_set(world.ecs, e, Chunk, {
|
||||
.x = i % chunk_size,
|
||||
.y = i / chunk_size,
|
||||
.x = i % world_size,
|
||||
.y = i / world_size,
|
||||
});
|
||||
|
||||
librg_entity_track(world.tracker, e);
|
||||
|
@ -162,15 +133,14 @@ static void world_tracker_update(void) {
|
|||
ecs_query_t *query = ecs_query_new(world.ecs, "Net.ClientInfo");
|
||||
|
||||
ecs_iter_t it = ecs_query_iter(query);
|
||||
static char buffer[16000] = {0};
|
||||
static int32_t datalen = 16000;
|
||||
char buffer[8096] = {0};
|
||||
|
||||
while (ecs_query_next(&it)) {
|
||||
ClientInfo *p = ecs_column(&it, ClientInfo, 1);
|
||||
|
||||
for (int i = 0; i < it.count; i++) {
|
||||
datalen = 16000;
|
||||
int32_t result = librg_world_write(world_tracker(), it.entities[i], buffer, &datalen, NULL);
|
||||
size_t datalen = 8096;
|
||||
int32_t result = librg_world_write(world_tracker(), p[i].peer, buffer, &datalen, NULL);
|
||||
|
||||
if (result > 0) {
|
||||
zpl_printf("[info] buffer size was not enough, please increase it by at least: %d\n", result);
|
||||
|
@ -178,7 +148,7 @@ static void world_tracker_update(void) {
|
|||
zpl_printf("[error] an error happened writing the world %d\n", result);
|
||||
}
|
||||
|
||||
pkt_world_write(MSG_ID_LIBRG_UPDATE, pkt_send_librg_update_encode(buffer, datalen), 1, p[i].peer);
|
||||
pkt_world_write(MSG_ID_LIBRG_UPDATE, pkt_send_librg_update_encode(buffer, datalen), 1, p[i].view_id, p[i].peer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@ typedef WORLD_PKT_READER(world_pkt_reader_proc);
|
|||
#define WORLD_PKT_WRITER(name) int32_t name(pkt_header *pkt, void *udata)
|
||||
typedef WORLD_PKT_WRITER(world_pkt_writer_proc);
|
||||
|
||||
int32_t world_init_minimal(uint16_t block_size, uint16_t chunk_size, uint16_t world_size, world_pkt_reader_proc *reader_proc, world_pkt_writer_proc *writer_proc);
|
||||
int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size, world_pkt_reader_proc *reader_proc, world_pkt_writer_proc *writer_proc);
|
||||
void world_setup_pkt_handlers(world_pkt_reader_proc *reader_proc, world_pkt_writer_proc *writer_proc);
|
||||
int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size);
|
||||
int32_t world_destroy(void);
|
||||
int32_t world_update(void);
|
||||
int32_t world_read(void* data, uint32_t datalen, void *udata);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
ECS_STRUCT(ClientInfo, {
|
||||
uintptr_t peer;
|
||||
uint16_t view_id;
|
||||
});
|
||||
|
||||
typedef struct {
|
||||
|
|
Loading…
Reference in New Issue