From 0a6f3ad291f0bc5bf41e32e14c43798c969a0eb3 Mon Sep 17 00:00:00 2001 From: hgn Date: Fri, 4 Apr 2025 21:20:27 +0100 Subject: [PATCH] clean up requests stuff --- src/ent_skateshop.c | 8 +- src/network.c | 250 +------------------------------- src/network.h | 23 --- src/network_requests.c | 318 +++++++++++++++++++++++++++++++++++++++++ src/network_requests.h | 41 ++++++ 5 files changed, 371 insertions(+), 269 deletions(-) create mode 100644 src/network_requests.c create mode 100644 src/network_requests.h diff --git a/src/ent_skateshop.c b/src/ent_skateshop.c index d82c621..18249b1 100644 --- a/src/ent_skateshop.c +++ b/src/ent_skateshop.c @@ -781,12 +781,14 @@ void ent_skateshop_render( vg_camera *cam ) f32 dist2 = v3_dist2( cam->pos, shop->transform.co ), maxdist = 50.0f; - if( dist2 > maxdist*maxdist ) continue; - ent_marker *mark_rack = af_arritm( &world->ent_marker, mdl_entity_id_id(shop->boards.id_rack)); + if( dist2 > maxdist*maxdist ) + continue; - if( !mark_rack ) + if( mdl_entity_id_type(shop->boards.id_rack) != k_ent_marker ) continue; + ent_marker *mark_rack = af_arritm( &world->ent_marker, mdl_entity_id_id(shop->boards.id_rack)); + u32 slot_count = VG_ARRAY_LEN(_skateshop.shop_view_slots); for( u32 i=0; i @@ -121,112 +122,6 @@ void network_send_region(void) k_nSteamNetworkingSend_Reliable, NULL ); } -static void network_send_request( netmsg_request *req, vg_msg *body, - void (*callback)( void *data, u32 data_size, u64 userdata, enum request_status status ), - u64 userdata ) -{ - u32 len = 0; - if( body ) - { - len = body->cur.co; - vg_info( "Request scoreboard. Info (%u):\n", body->cur.co ); - vg_msg_print( body, len ); - - if( body->error != k_vg_msg_error_OK ) - { - vg_error( "Body not OK\n" ); - return; - } - } - - if( callback ) - { - req->id = vg_pool_lru( &network_client.request_pool ); - if( req->id ) - { - vg_pool_watch( &network_client.request_pool, req->id ); - struct network_request *pn = vg_pool_item( &network_client.request_pool, req->id ); - pn->callback = callback; - pn->sendtime = vg.time_real; - pn->userdata = userdata; - pn->status = k_request_status_sent; - } - else - { - vg_error( "Unable to send request. Pool is full.\n" ); - return; - } - } - else - req->id = 0; - - SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( hSteamNetworkingSockets, network_client.remote, - req, sizeof(netmsg_request)+len, - k_nSteamNetworkingSend_Reliable, NULL ); -} - -static void network_scoreboard_callback( void *data, u32 data_size, u64 userdata, enum request_status status ) -{ - if( status == k_request_status_ok ) - { - vg_msg msg; - vg_msg_init( &msg, data, data_size ); - vg_msg_print( &msg, msg.max ); - - world_routes_recv_scoreboard( &_world.main, &msg, userdata, status ); - if( userdata == world_sfd.active_route_board ) - world_sfd_compile_active_scores(); - } - else - { - world_routes_recv_scoreboard( &_world.main, NULL, userdata, status ); - } -} - -/* mod_uid: world mod uid, - * route_uid: run name (just a string) - * week: - * 0 ALL TIME - * 1 CURRENT WEEK - * 2 ALL TIME + CURRENT WEEK - * . - * 10+ specific week index - */ -void network_request_scoreboard( const char *mod_uid, const char *route_uid, u32 week, u64 userdata ) -{ - if( !network_connected() ) - return; - - netmsg_request *req = alloca( sizeof(netmsg_request) + 512 ); - req->inetmsg_id = k_inetmsg_request; - - vg_msg data; - vg_msg_init( &data, req->buffer, 512 ); - vg_msg_wkvstr( &data, "endpoint", "scoreboard" ); - vg_msg_wkvstr( &data, "mod", mod_uid ); - vg_msg_wkvstr( &data, "route", route_uid ); - vg_msg_wkvnum( &data, "week", k_vg_msg_u32, 1, &week ); - network_send_request( req, &data, network_scoreboard_callback, userdata ); -} - -void network_publish_laptime( const char *mod_uid, const char *route_uid, f64 lap_time ) -{ - if( !network_connected() ) - return; - - i32 time_centiseconds = lap_time * 100.0; - - netmsg_request *req = alloca( sizeof(netmsg_request) + 512 ); - req->inetmsg_id = k_inetmsg_request; - - vg_msg data; - vg_msg_init( &data, req->buffer, 512 ); - vg_msg_wkvstr( &data, "endpoint", "setlap" ); - vg_msg_wkvstr( &data, "mod", mod_uid ); - vg_msg_wkvstr( &data, "route", route_uid ); - vg_msg_wkvnum( &data, "time", k_vg_msg_i32, 1, &time_centiseconds ); - network_send_request( req, &data, NULL, 0 ); -} static void network_request_rx_300_400( SteamNetworkingMessage_t *msg ) { @@ -238,115 +133,7 @@ static void network_request_rx_300_400( SteamNetworkingMessage_t *msg ) } else if( tmp->inetmsg_id == k_inetmsg_response ) { - netmsg_request *res = (netmsg_request *)msg->m_pData; - - if( (res->id == 0) || (res->id > NETWORK_MAX_REQUESTS) ) - { - vg_error( "Response with invalid ID: %u.\n", res->id ); - return; - } - - struct network_request *pn = vg_pool_item( &network_client.request_pool, res->id ); - if( pn->status == k_request_status_none ) - { - vg_error( "Response to inactive request (id %u)\n", res->id ); - return; - } - - u32 byte_count = msg->m_cbSize - sizeof(netmsg_request); - if( res->status == k_request_status_ok ) - { - if( pn->callback ) - pn->callback( res->buffer, byte_count, pn->userdata, k_request_status_ok ); - - vg_pool_unwatch( &network_client.request_pool, res->id ); - pn->status = k_request_status_none; - } - else if( res->status == k_request_status_transfer_header ) - { - if( network_client.recieving_request_id ) - { - vg_error( "Transfer for previous request (%u) interrupted by new one (%u)\n", - network_client.recieving_request_id, res->id ); - - struct network_request *prev = vg_pool_item( &network_client.request_pool, network_client.recieving_request_id ); - vg_pool_unwatch( &network_client.request_pool, network_client.recieving_request_id ); - prev->status = k_request_status_none; - - network_client.recieving_request_id = 0; - network_client.recieve_offset = 0; - network_client.data_buffer_recieve_size = 0; - } - - struct netmsg_transfer_header *header = (void *)res->buffer; - - if( header->data_size > 1024*1024*4 ) - { - vg_error( "Transfer too large to handle! Size: %u bytes\n", header->data_size ); - vg_pool_unwatch( &network_client.request_pool, res->id ); - pn->status = k_request_status_none; - return; - } - - network_client.recieving_request_id = res->id; - network_client.recieve_offset = 0; - network_client.data_buffer_recieve_size = header->data_size; - - pn->status = k_request_status_receiving; - } - else if( res->status == k_request_status_transfer_continue ) - { - if( network_client.recieving_request_id != res->id ) - { - vg_error( "Transfer protocal fault, against requests %u and %u. Discarding.\n", - network_client.recieving_request_id, res->id ); - - struct network_request *prev = vg_pool_item( &network_client.request_pool, network_client.recieving_request_id ); - vg_pool_unwatch( &network_client.request_pool, network_client.recieving_request_id ); - vg_pool_unwatch( &network_client.request_pool, res->id ); - prev->status = k_request_status_none; - pn->status = k_request_status_none; - network_client.recieving_request_id = 0; - network_client.recieve_offset = 0; - network_client.data_buffer_recieve_size = 0; - return; - } - - bool end = 0; - if( network_client.recieve_offset + byte_count >= network_client.data_buffer_recieve_size ) - { - end = 1; - byte_count = network_client.data_buffer_recieve_size - network_client.recieve_offset; - } - - memcpy( network_client.data_buffer + network_client.recieve_offset, res->buffer, byte_count ); - network_client.recieve_offset += byte_count; - - if( end ) - { - vg_success( "Transfer finished! (%u bytes)\n", network_client.recieve_offset ); - if( pn->callback ) - { - pn->callback( network_client.data_buffer, network_client.data_buffer_recieve_size, - pn->userdata, k_request_status_ok ); - } - - vg_pool_unwatch( &network_client.request_pool, res->id ); - pn->status = k_request_status_none; - - network_client.recieving_request_id = 0; - network_client.recieve_offset = 0; - network_client.data_buffer_recieve_size = 0; - } - - // TODO: Timeout request & disconnecting from server - } - else - { - vg_pool_unwatch( &network_client.request_pool, res->id ); - vg_warn( "Server response to #%d: %d\n", (i32)res->id, res->status ); - pn->status = k_request_status_none; - } + _net_handle_response_message( msg ); } } @@ -413,22 +200,8 @@ static void network_disconnect(void) { netplayers.list[i].active = 0; } - - /* return the infinity stones */ - network_client.data_buffer_recieve_size = 0; - network_client.recieve_offset = 0; - network_client.recieving_request_id = 0; - for( u32 i=0; istatus != k_request_status_none ) - { - vg_warn( "Clipping request #%u. Timeout of some kind\n", i ); - request->status = k_request_status_none; - vg_pool_unwatch( &network_client.request_pool, i+1 ); - } - } + + _net_requests_reset(); } void network_status_string( vg_str *str, u32 *colour ) @@ -881,18 +654,7 @@ void network_init(void) vg_console_reg_var( "auto_connect", &network_client.auto_connect, k_var_dtype_i32, VG_VAR_PERSISTENT ); if( steam_ready ) { - u32 alloc_size = sizeof(struct network_request)*NETWORK_MAX_REQUESTS; - network_client.request_buffer = vg_linear_alloc( vg_mem.rtmemory, alloc_size ); - memset( network_client.request_buffer, 0, alloc_size ); - network_client.data_buffer = vg_linear_alloc( vg_mem.rtmemory, 4*1024*1024 ); - - vg_pool *pool = &network_client.request_pool; - pool->buffer = network_client.request_buffer; - pool->count = NETWORK_MAX_REQUESTS; - pool->stride = sizeof( struct network_request ); - pool->offset = offsetof( struct network_request, poolnode ); - vg_pool_init( pool ); - + _net_requests_init(); steam_register_callback( k_iSteamNetConnectionStatusChangedCallBack, on_server_connect_status ); steam_register_callback( k_iPersonaStateChange, on_persona_state_change ); request_auth_ticket(); @@ -911,3 +673,5 @@ void network_end(void) hSteamNetworkingSockets, network_client.remote, 0, NULL, 1 ); } } + +#include "network_requests.c" diff --git a/src/network.h b/src/network.h index f82e855..cb3649c 100644 --- a/src/network.h +++ b/src/network.h @@ -54,29 +54,6 @@ struct network_client i32 auto_connect; - struct network_request - { - vg_pool_node poolnode; - void (*callback)( void *data, u32 data_size, u64 userdata, enum request_status status ); - f64 sendtime; - u64 userdata; - - enum status - { - k_request_status_none, - k_request_status_sent, - k_request_status_receiving, - } - status; - } - *request_buffer; - vg_pool request_pool; - - void *data_buffer; - u32 data_buffer_recieve_size; - u32 recieve_offset; - u8 recieving_request_id; - SteamNetworkingIPAddr ip; char host_port[8], host_adress[256]; bool ip_resolved; diff --git a/src/network_requests.c b/src/network_requests.c new file mode 100644 index 0000000..3338991 --- /dev/null +++ b/src/network_requests.c @@ -0,0 +1,318 @@ +#include "network_requests.h" + +struct _net_requests _net_requests; + +const char *request_status_string( enum request_status status ) +{ + if( (status >= 0) && (status < 100) ) + { + if( status == k_request_status_client_error ) return "Client Error"; + else if( status == k_request_status_invalid_endpoint ) return "Invalid Endpoint"; + else if( status == k_request_status_unauthorized ) return "Unauthorized"; + else if( status == k_request_status_too_many_requests )return "Too many requests"; + else return "Invalid client status code"; + } + else if( (status >= 100) && (status < 200) ) + { + if( status == k_request_status_server_error ) return "Server error"; + else if( status == k_request_status_out_of_memory ) return "Out of memory"; + else if( status == k_request_status_database_error ) return "Database error"; + else return "Invalid server status code"; + } + else if( (status >= 200) && (status <= 255) ) + { + if( status == k_request_status_ok ) return "OK"; + else if( status == k_request_status_not_found ) return "Not found"; + else if( status == k_request_status_transfer_header ) return "Transfer header"; + else if( status == k_request_status_transfer_continue )return "Transfer continue"; + else return "Invalid content code"; + } + else return "Status code out of range"; +} + +static void log_request_status( net_request *req, const char *comment ) +{ + const char *associated_username = "local"; + u16 pool_id = vg_pool_id( &_net_requests.request_pool, req ); + + const char *request_state_str = (const char *[]) + { + [k_request_state_none] = "None", + [k_request_state_sent] = "Sent", + [k_request_state_receiving] = "Recieving", + [k_request_state_finished] = "Finished", + [k_request_state_error] = "Error", + [k_request_state_max ] = NULL + } + [ req->state ]; + + const char *colour = (const char *[]) + { + KRED, KGRN, KYEL, KBLU, + KMAG, KCYN + }[ pool_id % 6 ]; + + if( comment ) + vg_low( "req[%s%s##%hu" KWHT "] State: %s (%s)\n", colour, associated_username, pool_id, request_state_str, comment ); + else + vg_low( "req[%s%s##%hu" KWHT "] State: %s\n", colour, associated_username, pool_id, request_state_str ); +} + +void network_send_request( netmsg_request *packet, vg_msg *body, + void (*callback)( void *data, u32 data_size, u64 userdata, enum request_status status ), + u64 userdata ) +{ + u32 len = 0; + if( body ) + { + len = body->cur.co; + vg_msg_print( body, len ); + + if( body->error != k_vg_msg_error_OK ) + { + vg_error( "Body not OK\n" ); + return; + } + } + + if( callback ) + { + packet->id = vg_pool_lru( &_net_requests.request_pool ); + if( packet->id ) + { + vg_pool_watch( &_net_requests.request_pool, packet->id ); + net_request *req = vg_pool_item( &_net_requests.request_pool, packet->id ); + req->callback = callback; + req->sendtime = vg.time_real; + req->userdata = userdata; + req->state = k_request_state_sent; + log_request_status( req, NULL ); + } + else + { + vg_error( "Unable to send request. Pool is full.\n" ); + return; + } + } + else + packet->id = 0; + + SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( hSteamNetworkingSockets, network_client.remote, + packet, sizeof(netmsg_request)+len, + k_nSteamNetworkingSend_Reliable, NULL ); +} + +static void network_scoreboard_callback( void *data, u32 data_size, u64 userdata, enum request_status status ) +{ + if( status == k_request_status_ok ) + { + vg_msg msg; + vg_msg_init( &msg, data, data_size ); + vg_msg_print( &msg, msg.max ); + + world_routes_recv_scoreboard( &_world.main, &msg, userdata, status ); + if( userdata == world_sfd.active_route_board ) + world_sfd_compile_active_scores(); + } + else + world_routes_recv_scoreboard( &_world.main, NULL, userdata, status ); +} + +/* mod_uid: world mod uid, + * route_uid: run name (just a string) + * week: + * 0 ALL TIME + * 1 CURRENT WEEK + * 2 ALL TIME + CURRENT WEEK + * . + * 10+ specific week index + */ +void network_request_scoreboard( const char *mod_uid, const char *route_uid, u32 week, u64 userdata ) +{ + if( !network_connected() ) + return; + + netmsg_request *packet = alloca( sizeof(netmsg_request) + 512 ); + packet->inetmsg_id = k_inetmsg_request; + + vg_msg data; + vg_msg_init( &data, packet->buffer, 512 ); + vg_msg_wkvstr( &data, "endpoint", "scoreboard" ); + vg_msg_wkvstr( &data, "mod", mod_uid ); + vg_msg_wkvstr( &data, "route", route_uid ); + vg_msg_wkvnum( &data, "week", k_vg_msg_u32, 1, &week ); + network_send_request( packet, &data, network_scoreboard_callback, userdata ); +} + +void network_publish_laptime( const char *mod_uid, const char *route_uid, f64 lap_time ) +{ + if( !network_connected() ) + return; + + i32 time_centiseconds = lap_time * 100.0; + + netmsg_request *packet = alloca( sizeof(netmsg_request) + 512 ); + packet->inetmsg_id = k_inetmsg_request; + + vg_msg data; + vg_msg_init( &data, packet->buffer, 512 ); + vg_msg_wkvstr( &data, "endpoint", "setlap" ); + vg_msg_wkvstr( &data, "mod", mod_uid ); + vg_msg_wkvstr( &data, "route", route_uid ); + vg_msg_wkvnum( &data, "time", k_vg_msg_i32, 1, &time_centiseconds ); + network_send_request( packet, &data, NULL, 0 ); +} + +static void _delete_request( net_request *request ) +{ + vg_pool_unwatch( &_net_requests.request_pool, vg_pool_id( &_net_requests.request_pool, request ) ); + request->state = k_request_state_none; +} + +static void _transfer_reset(void) +{ + _net_requests.recieving_request_id = 0; + _net_requests.recieve_offset = 0; + _net_requests.data_buffer_recieve_size = 0; +} + +void _net_handle_response_message( SteamNetworkingMessage_t *msg ) +{ + netmsg_request *response = (netmsg_request *)msg->m_pData; + + if( (response->id == 0) || (response->id > NETWORK_MAX_REQUESTS) ) + { + vg_error( "Response with invalid ID: %u.\n", response->id ); + return; + } + + net_request *request = vg_pool_item( &_net_requests.request_pool, response->id ); + if( request->state == k_request_state_none ) + { + vg_error( "Response to inactive request (id %u)\n", response->id ); + return; + } + + u32 byte_count = msg->m_cbSize - sizeof(netmsg_request); + if( response->status == k_request_status_ok ) + { + request->state = k_request_state_finished; + log_request_status( request, "200" ); + + if( request->callback ) + request->callback( response->buffer, byte_count, request->userdata, k_request_status_ok ); + + vg_pool_unwatch( &_net_requests.request_pool, response->id ); + request->state = k_request_state_none; + } + else if( response->status == k_request_status_transfer_header ) + { + u8 old_id = _net_requests.recieving_request_id; + if( old_id ) + { + net_request *old_request = vg_pool_item( &_net_requests.request_pool, old_id ); + old_request->state = k_request_state_error; + log_request_status( old_request, "Interrupted by new header" ); + _delete_request( old_request ); + _transfer_reset(); + } + + struct netmsg_transfer_header *header = (void *)response->buffer; + if( header->data_size > 1024*1024*4 ) + { + request->state = k_request_state_error; + log_request_status( request, "Header specified size too large (>4mb)" ); + _delete_request( request ); + return; + } + + _transfer_reset(); + _net_requests.recieving_request_id = response->id; + _net_requests.data_buffer_recieve_size = header->data_size; + + request->state = k_request_state_receiving; + log_request_status( request, "Valid" ); + } + else if( response->status == k_request_status_transfer_continue ) + { + u8 current_id = _net_requests.recieving_request_id; + if( current_id != response->id ) + { + net_request *current = vg_pool_item( &_net_requests.request_pool, current_id ); + current->state = k_request_state_error; + request->state = k_request_state_error; + log_request_status( current, "Transfer protocol fault" ); + log_request_status( request, "Transfer protocol fault" ); + _delete_request( current ); + _delete_request( request ); + _transfer_reset(); + return; + } + + bool end = 0; + if( _net_requests.recieve_offset + byte_count >= _net_requests.data_buffer_recieve_size ) + { + end = 1; + byte_count = _net_requests.data_buffer_recieve_size - _net_requests.recieve_offset; + } + + memcpy( _net_requests.data_buffer + _net_requests.recieve_offset, response->buffer, byte_count ); + _net_requests.recieve_offset += byte_count; + + if( end ) + { + request->state = k_request_state_finished; + log_request_status( request, NULL ); + + if( request->callback ) + { + request->callback( _net_requests.data_buffer, _net_requests.data_buffer_recieve_size, + request->userdata, k_request_status_ok ); + } + + _delete_request( request ); + _transfer_reset(); + } + } + else + { + request->state = k_request_state_error; + log_request_status( request, request_status_string(response->status) ); + _delete_request( request ); + } +} + +void _net_requests_init(void) +{ + u32 alloc_size = sizeof(net_request)*NETWORK_MAX_REQUESTS; + _net_requests.request_buffer = vg_linear_alloc( vg_mem.rtmemory, alloc_size ); + memset( _net_requests.request_buffer, 0, alloc_size ); + + _net_requests.data_buffer = vg_linear_alloc( vg_mem.rtmemory, 4*1024*1024 ); + + vg_pool *pool = &_net_requests.request_pool; + pool->buffer = _net_requests.request_buffer; + pool->count = NETWORK_MAX_REQUESTS; + pool->stride = sizeof( net_request ); + pool->offset = offsetof( net_request, poolnode ); + vg_pool_init( pool ); +} + +void _net_requests_reset(void) +{ + /* return the infinity stones */ + _net_requests.data_buffer_recieve_size = 0; + _net_requests.recieve_offset = 0; + _net_requests.recieving_request_id = 0; + for( u32 i=0; istate != k_request_state_none ) + { + vg_warn( "Clipping request #%u. Timeout of some kind\n", i ); + request->state = k_request_state_none; + vg_pool_unwatch( &_net_requests.request_pool, i+1 ); + } + } +} diff --git a/src/network_requests.h b/src/network_requests.h new file mode 100644 index 0000000..e376ad1 --- /dev/null +++ b/src/network_requests.h @@ -0,0 +1,41 @@ +#pragma once +#include "network.h" + +typedef struct net_request net_request; +struct net_request +{ + vg_pool_node poolnode; + void (*callback)( void *data, u32 data_size, u64 userdata, enum request_status status ); + f64 sendtime; + u64 userdata; + + enum net_request_state + { + k_request_state_none, + k_request_state_sent, + k_request_state_receiving, + k_request_state_finished, + k_request_state_error, + k_request_state_max + } + state; +}; + +struct _net_requests +{ + net_request *request_buffer; + vg_pool request_pool; + + void *data_buffer; + u32 data_buffer_recieve_size; + u32 recieve_offset; + u8 recieving_request_id; +} +extern _net_requests; + +void network_send_request( netmsg_request *req, vg_msg *body, + void (*callback)( void *data, u32 data_size, u64 userdata, enum request_status status ), + u64 userdata ); +void _net_handle_response_message( SteamNetworkingMessage_t *msg ); +void _net_requests_init(void); +void _net_requests_reset(void); -- 2.25.1