network: rework view_id

isolation_bkp/dynres
Dominik Madarász 2022-07-31 12:24:31 +02:00
parent 3b40354054
commit a2f76237f8
9 changed files with 80 additions and 84 deletions

View File

@ -110,6 +110,10 @@ void game_world_view_set_active(world_view *view) {
camera_set_follow(view->owner_id);
}
size_t game_world_view_count(void) {
return zpl_buffer_count(world_viewers);
}
void flecs_dash_init() {
#if 0
ECS_IMPORT(world_ecs(), FlecsDash);

View File

@ -26,6 +26,7 @@ void game_render();
//~ NOTE(zaklaus): world view management
world_view *game_world_view_get_active(void);
world_view *game_world_view_get(uint16_t idx);
size_t game_world_view_count(void);
void game_world_view_set_active_by_idx(uint16_t idx);
void game_world_view_set_active(world_view *view);
void game_world_view_cycle_active(int8_t dir);

View File

@ -24,6 +24,7 @@ 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;
@ -32,7 +33,6 @@ int32_t network_init() {
int32_t network_destroy() {
enet_deinitialize();
return 0;
}
//~ NOTE(zaklaus): client
@ -40,61 +40,63 @@ 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);
host = enet_host_create(NULL, 1, 2, 0, 0);
peer = enet_host_connect(host, &address, 2, 0);
if (peer == NULL) {
zpl_printf("[ERROR] Cannot connect to specicied server: %s:%d\n", hostname, port);
return 1;
}
world = librg_world_create();
librg_world_userdata_set(world, peer);
return 0;
}
int32_t network_client_disconnect() {
enet_peer_disconnect(peer, 0);
enet_host_destroy(host);
librg_world_destroy(world);
peer = NULL;
host = NULL;
world = NULL;
return 0;
}
int32_t network_client_tick() {
ENetEvent event = {0};
while (enet_host_service(host, &event, 1) > 0) {
switch (event.type) {
case ENET_EVENT_TYPE_CONNECT: {
zpl_printf("[INFO] We connected to the server.\n");
pkt_00_init_send(0);
for (uint32_t i = 0; i < game_world_view_count(); i++) {
pkt_00_init_send(i);
}
} break;
case ENET_EVENT_TYPE_DISCONNECT:
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT: {
zpl_printf("[INFO] We disconnected from server.\n");
} break;
case ENET_EVENT_TYPE_RECEIVE: {
if (!world_read(event.packet->data, (uint32_t)event.packet->dataLength, event.peer)) {
zpl_printf("[INFO] Server sent us an unsupported packet.\n");
}
/* Clean up the packet now that we're done using it. */
enet_packet_destroy(event.packet);
} break;
case ENET_EVENT_TYPE_NONE: break;
}
}
return 0;
}
@ -105,59 +107,59 @@ network_client_stats
network_client_fetch_stats(void) {
if (!network_client_is_connected())
return (network_client_stats){0};
network_client_stats stats = {0};
stats.incoming_total = peer->incomingDataTotal;
stats.total_received = peer->totalDataReceived;
stats.outgoing_total = peer->outgoingDataTotal;
stats.total_sent = peer->totalDataSent;
static double next_measure = 0.0;
static float incoming_bandwidth = 0.0f;
static float outgoing_bandwidth = 0.0f;
if (next_measure < zpl_time_rel()) {
#define MAX_RATE_SAMPLES 8
static uint64_t last_total_sent = 0;
static uint64_t last_total_recv = 0;
static uint64_t rolling_counter = 0;
static uint64_t sent_buffer[MAX_RATE_SAMPLES] = {0};
static uint64_t recv_buffer[MAX_RATE_SAMPLES] = {0};
static uint64_t sent_buffer[MAX_RATE_SAMPLES] = {0};
static uint64_t recv_buffer[MAX_RATE_SAMPLES] = {0};
uint64_t sent_delta = stats.total_sent - last_total_sent;
uint64_t recv_delta = stats.total_received - last_total_recv;
last_total_sent = stats.total_sent;
last_total_recv = stats.total_received;
sent_buffer[rolling_counter % MAX_RATE_SAMPLES] = sent_delta;
recv_buffer[rolling_counter % MAX_RATE_SAMPLES] = recv_delta;
++rolling_counter;
for (int i = 0; i < MAX_RATE_SAMPLES; i++) {
stats.incoming_bandwidth += recv_buffer[i];
stats.outgoing_bandwidth += sent_buffer[i];
}
incoming_bandwidth = stats.incoming_bandwidth /= MAX_RATE_SAMPLES;
outgoing_bandwidth = stats.outgoing_bandwidth /= MAX_RATE_SAMPLES;
next_measure = zpl_time_rel() + 1.0;
} else {
stats.incoming_bandwidth = incoming_bandwidth;
stats.outgoing_bandwidth = outgoing_bandwidth;
}
stats.packets_sent = peer->totalPacketsSent;
stats.packets_lost = peer->totalPacketsLost;
if (stats.packets_sent > 0) {
stats.packet_loss = stats.packets_lost / (float)stats.packets_sent;
}
stats.ping = peer->roundTripTime;
stats.low_ping = peer->lowestRoundTripTime;
return stats;
}
@ -165,19 +167,20 @@ network_client_fetch_stats(void) {
int32_t network_server_start(const char *host, uint16_t port) {
(void)host;
ENetAddress address = {0};
address.host = ENET_HOST_ANY;
address.port = port;
server = enet_host_create(&address, 8, 2, 0, 0);
if (server == NULL) {
zpl_printf("[ERROR] An error occured while trying to create a server host.\n");
return 1;
}
clientinfo_query = ecs_query_new(world_ecs(), "components.ClientInfo");
return 0;
}
@ -197,41 +200,60 @@ int32_t network_server_tick(void) {
case ENET_EVENT_TYPE_DISCONNECT:
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT: {
zpl_printf("[INFO] A user %d disconnected.\n", event.peer->incomingPeerID);
if (event.peer->data) {
player_despawn((ecs_entity_t)event.peer->data);
event.peer->data = 0;
network_server_despawn_viewers(event.peer);
}
} break;
case ENET_EVENT_TYPE_RECEIVE: {
if (!world_read(event.packet->data, (uint32_t)event.packet->dataLength, event.peer)) {
zpl_printf("[INFO] User %d sent us a malformed packet.\n", event.peer->incomingPeerID);
}
/* Clean up the packet now that we're done using it. */
enet_packet_destroy(event.packet);
} break;
case ENET_EVENT_TYPE_NONE: break;
}
}
return 0;
}
void network_server_assign_entity(void *peer_id, uint64_t ent_id) {
ENetPeer *peer = (ENetPeer *)peer_id;
peer->data = (void*)ent_id;
void network_server_despawn_viewers(void *peer_id) {
ecs_iter_t it = ecs_query_iter(clientinfo_query);
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) {
player_despawn(it.entities[i]);
}
}
}
}
uint64_t network_server_get_entity(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;
}
ENetPeer *peer = (ENetPeer *)peer_id;
ZPL_ASSERT(peer->data);
return (uint64_t)peer->data;
ecs_iter_t it = ecs_query_iter(clientinfo_query);
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 == view_id) {
return it.entities[i];
}
}
}
return 0;
}
//~ NOTE(zaklaus): messaging

View File

@ -39,8 +39,8 @@ network_client_fetch_stats(void);
int32_t network_server_start(const char *host, uint16_t port);
int32_t network_server_stop(void);
int32_t network_server_tick(void);
void network_server_assign_entity(void *peer_id, uint64_t ent_id);
uint64_t network_server_get_entity(void *peer_id);
void network_server_despawn_viewers(void *peer_id);
uint64_t network_server_get_entity(void *peer_id, uint16_t view_id);
// NOTE(zaklaus): messaging
int32_t network_msg_send(void *peer_id, void *data, size_t datalen, uint16_t channel_id);

View File

@ -34,7 +34,6 @@ int32_t pkt_00_init_handler(pkt_header *header) {
if (game_get_kind() == GAMEKIND_SINGLE) peer_id = ent_id;
else network_server_assign_entity(header->udata, ent_id);
ecs_set(world_ecs(), ent_id, ClientInfo, {.peer = peer_id, .view_id = header->view_id });
pkt_01_welcome_send(world_seed(), peer_id, header->view_id, ent_id, world_chunk_size(), world_chunk_amount());

View File

@ -29,7 +29,7 @@ int32_t pkt_01_welcome_handler(pkt_header *header) {
world_view *view = game_world_view_get(header->view_id);
zpl_printf("[INFO] initializing read-only world view ...\n");
zpl_printf("[INFO] initializing read-only world view id: %d...\n", header->view_id);
world_view_init(view, table.seed, table.ent_id, table.chunk_size, table.world_size);
game_world_view_set_active(view);
return 0;

View File

@ -33,7 +33,7 @@ size_t pkt_send_keystate_send(uint16_t view_id,
int32_t pkt_send_keystate_handler(pkt_header *header) {
pkt_send_keystate table;
PKT_IF(pkt_msg_decode(header, pkt_send_keystate_desc, pkt_pack_desc_args(pkt_send_keystate_desc), PKT_STRUCT_PTR(&table)));
ecs_entity_t e = network_server_get_entity(header->udata);
ecs_entity_t e = network_server_get_entity(header->udata, header->view_id);
if (!world_entity_valid(e))
return 1;

View File

@ -26,6 +26,7 @@ static bool request_shutdown;
#include "gui/inventory.c"
void platform_init() {
SetTraceLogLevel(LOG_ERROR);
InitWindow(screenWidth, screenHeight, "eco2d");
SetWindowState(/*FLAG_WINDOW_UNDECORATED|*/FLAG_WINDOW_MAXIMIZED|FLAG_WINDOW_RESIZABLE|FLAG_MSAA_4X_HINT);

View File

@ -1,31 +0,0 @@
#include "platform.h"
#include <stdio.h>
uint8_t is_running;
void platform_init() {
printf("eco2d-cli\n");
is_running = 1;
}
void platform_shutdown() {
printf("\nBye!\n");
is_running = 0;
}
void platform_input() {
}
uint8_t platform_is_running() {
return is_running;
}
float platform_frametime() {
return 1.0f;
}
void platform_render() {
zpl_printf("o");
zpl_sleep_ms(1000);
}