network: rework view_id
parent
3b40354054
commit
a2f76237f8
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue