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<slot_count; i++ )
{
#include "gui.h"
#include "ent_region.h"
#include "vg/vg_loader.h"
+#include "network_requests.h"
#ifdef _WIN32
#include <winsock2.h>
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 )
{
}
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 );
}
}
{
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; i<NETWORK_MAX_REQUESTS; i ++ )
- {
- struct network_request *request = &network_client.request_buffer[ i ];
-
- if( request->status != 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 )
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();
hSteamNetworkingSockets, network_client.remote, 0, NULL, 1 );
}
}
+
+#include "network_requests.c"
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;
--- /dev/null
+#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; i<NETWORK_MAX_REQUESTS; i ++ )
+ {
+ net_request *request = &_net_requests.request_buffer[ i ];
+
+ if( request->state != 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 );
+ }
+ }
+}
--- /dev/null
+#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);