X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=server.c;h=270e916c8c1a7e0a7bb335c6cba8477284f763bf;hb=5f5d02725031cad23f1cab3290b8a9d661c89728;hp=7d8e0e36a28d554bc2add7e18bb4b77ea7a65681;hpb=0945c6c301e38138b6ac54a02d5b3aea602de526;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/server.c b/server.c index 7d8e0e3..270e916 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,6 @@ -// Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved +/* + * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved + */ /* * This server application requires steamclient.so to be present in the @@ -9,11 +11,11 @@ #define _DEFAULT_SOURCE #include #include +#include volatile sig_atomic_t sig_stop; -void inthandler( int signum ) -{ +static void inthandler( int signum ) { sig_stop = 1; } @@ -24,13 +26,20 @@ void inthandler( int signum ) #include "vg/vg_steam_http.h" #include "vg/vg_steam_auth.h" #include "network_msg.h" +#include "highscores.h" + +/* implementation */ +#include "highscores.c" -void *hSteamHTTP, - *hSteamNetworkingSockets; +static const u64 k_connection_unauthorized = 0xffffffffffffffff; -u8 steam_symetric_key[ k_nSteamEncryptedAppTicketSymmetricKeyLen ]; -HSteamNetPollGroup client_pollgroup; +static void *hSteamHTTP, + *hSteamNetworkingSockets; +static u8 steam_symetric_key[ k_nSteamEncryptedAppTicketSymmetricKeyLen ]; +static HSteamNetPollGroup client_pollgroup; + +#if 0 static void recieve_http( void *callresult, void *context ) { HTTPRequestCompleted_t *result = callresult; @@ -40,16 +49,33 @@ static void recieve_http( void *callresult, void *context ) SteamAPI_ISteamHTTP_GetHTTPResponseBodySize( hSteamHTTP, request, &size ); - u8 *buffer = malloc( size ); + u8 *buffer = vg_alloc( size ); SteamAPI_ISteamHTTP_GetHTTPResponseBodyData( hSteamHTTP, request, buffer, size ); buffer[size-1] = '\0'; vg_info( "%s\n", (char *)buffer ); - free( buffer ); + vg_free( buffer ); SteamAPI_ISteamHTTP_ReleaseHTTPRequest( hSteamHTTP, result->m_hRequest ); } +#endif + +static u64_steamid get_connection_authsteamid( SteamNetworkingMessage_t *msg ) +{ + i64 userdata = SteamAPI_ISteamNetworkingSockets_GetConnectionUserData( + hSteamNetworkingSockets, msg->m_conn ); + + return *((u64_steamid *)&userdata); +} + +static void set_connection_authsteamid(HSteamNetConnection con, u64_steamid id) +{ + i64 userdata = *((i64 *)&id); + + SteamAPI_ISteamNetworkingSockets_SetConnectionUserData( + hSteamNetworkingSockets, con, userdata ); +} static void new_client_connecting( HSteamNetConnection client ) { @@ -62,6 +88,9 @@ static void new_client_connecting( HSteamNetConnection client ) SteamAPI_ISteamNetworkingSockets_SetConnectionPollGroup( hSteamNetworkingSockets, client, client_pollgroup ); + + /* Just to be sure */ + set_connection_authsteamid( client, -1 ); } else { @@ -83,8 +112,8 @@ static void on_connect_status( CallbackMsg_t *msg ) vg_info( " Connection status changed for %lu\n", info->m_hConn ); vg_info( " %s -> %s\n", - string_ESteamNetworkingConnectionState(info->m_info.m_eState), - string_ESteamNetworkingConnectionState(info->m_eOldState) ); + string_ESteamNetworkingConnectionState(info->m_eOldState), + string_ESteamNetworkingConnectionState(info->m_info.m_eState) ); if( info->m_info.m_eState==k_ESteamNetworkingConnectionState_Connecting ) { @@ -92,13 +121,163 @@ static void on_connect_status( CallbackMsg_t *msg ) } } +static void on_inet_auth( SteamNetworkingMessage_t *msg ) +{ + if( get_connection_authsteamid( msg ) != k_connection_unauthorized ) + { + vg_warn( "Already authorized this user but app ticket was sent" + " again (%u)\n", msg->m_conn ); + return; + } + + vg_low( "Attempting to verify user\n" ); + + if( msg->m_cbSize < sizeof(netmsg_auth) ) + { + vg_error( "Malformed auth ticket, too small (%u)\n", msg->m_conn ); + return; + } + + netmsg_auth *auth = msg->m_pData; + + if( msg->m_cbSize < sizeof(netmsg_auth)+auth->ticket_length || + auth->ticket_length > 1024 ) + { + vg_error( "Malformed auth ticket, ticket_length incorrect (%u)\n", + auth->ticket_length ); + return; + } + + u8 decrypted[1024]; + u32 ticket_len = 1024; + + int success = SteamEncryptedAppTicket_BDecryptTicket( + auth->ticket, auth->ticket_length, decrypted, + &ticket_len, steam_symetric_key, + k_nSteamEncryptedAppTicketSymmetricKeyLen ); + + if( !success ) + { + vg_error( "Failed to decrypt users ticket (client %u)\n", msg->m_conn ); + vg_error( " ticket length: %u\n", auth->ticket_length ); + + SteamAPI_ISteamNetworkingSockets_CloseConnection( + hSteamNetworkingSockets, + msg->m_conn, 0, NULL, 1 ); + return; + } + + if( SteamEncryptedAppTicket_GetTicketIssueTime( decrypted, ticket_len )) + { + RTime32 ctime = time(NULL), + tickettime = SteamEncryptedAppTicket_GetTicketIssueTime( + decrypted, ticket_len ), + expiretime = tickettime + 24*3*60*60; + + if( ctime > expiretime ) + { + vg_error( "Ticket expired (client %u)\n", msg->m_conn ); + + /* TODO: Send expired information */ + SteamAPI_ISteamNetworkingSockets_CloseConnection( + hSteamNetworkingSockets, + msg->m_conn, 0, NULL, 1 ); + return; + } + } + + CSteamID steamid; + SteamEncryptedAppTicket_GetTicketSteamID( decrypted, ticket_len, &steamid ); + vg_success( "User is authenticated! steamid %lu (%u)\n", + steamid.m_unAll64Bits, msg->m_conn ); + + set_connection_authsteamid( msg->m_conn, steamid.m_unAll64Bits ); +} + +static int inet_require_auth( SteamNetworkingMessage_t *msg ) +{ + if( get_connection_authsteamid( msg ) == k_connection_unauthorized ) + { + vg_warn( "Unauthorized request! Disconnecting client: %u\n", + msg->m_conn ); + + SteamAPI_ISteamNetworkingSockets_CloseConnection( + hSteamNetworkingSockets, + msg->m_conn, 0, NULL, 1 ); + + return 0; + } + else return 1; +} + +static void on_inet_score_request( SteamNetworkingMessage_t *msg ) +{ + if( !inet_require_auth(msg) ) return; + + SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( + hSteamNetworkingSockets, msg->m_conn, + &scoreboard_client_data, sizeof(netmsg_scoreboard), + k_nSteamNetworkingSend_Reliable, NULL ); +} + +static void on_inet_set_nickname( SteamNetworkingMessage_t *msg ) +{ + if(!inet_require_auth(msg)) return; + + u64_steamid steamid = get_connection_authsteamid(msg); + netmsg_set_nickname *setnick = msg->m_pData; + if( msg->m_cbSize < sizeof(netmsg_set_nickname) ) + { + vg_warn( "Invalid nickname request from client: %u, steamid: %lu\n", + msg->m_conn, steamid ); + return; + } + + highscore_set_user_nickname( steamid, setnick->nickname ); +} + +static void on_inet_set_score( SteamNetworkingMessage_t *msg ) +{ + if(!inet_require_auth(msg)) return; + + u64_steamid steamid = get_connection_authsteamid(msg); + + if( msg->m_cbSize < sizeof(netmsg_set_score) ) + { + vg_warn( "Invalid set score post from client: %u, steamid: %lu\n", + msg->m_conn, steamid ); + return; + } + + netmsg_set_score *info = msg->m_pData; + + if( msg->m_cbSize < sizeof(netmsg_set_score) + + sizeof(struct netmsg_score_record)*info->record_count ) + { + vg_warn( "Malformed set score post from client: %u, steamid: %lu\n", + msg->m_conn, steamid ); + return; + } + + for( int i=0; irecord_count; i++ ) + { + highscore_record temp; + temp.trackid = info->records[i].trackid; + temp.datetime = time(NULL); + temp.playerid = steamid; + temp.points = info->records[i].points; + temp.time = info->records[i].time; + + highscores_push_record( &temp ); + } +} + static void poll_connections(void) { SteamNetworkingMessage_t *messages[32]; int len; - while(1) - { + while(1){ len = SteamAPI_ISteamNetworkingSockets_ReceiveMessagesOnPollGroup( hSteamNetworkingSockets, client_pollgroup, messages, vg_list_size(messages) ); @@ -106,35 +285,28 @@ static void poll_connections(void) if( len <= 0 ) return; - for( int i=0; im_cbSize < sizeof(netmsg_blank) ) - { + if( msg->m_cbSize < sizeof(netmsg_blank) ){ vg_warn( "Discarding message (too small: %d)\n", msg->m_cbSize ); continue; } netmsg_blank *tmp = msg->m_pData; - if( tmp->inetmsg_id == k_inetmsg_scores_request ) - { - vg_log( "Recieved score request, sending records. (id: %u)\n", - msg->m_conn ); - - /* Send back current scores */ - u32 data_size = sizeof(netmsg_scores_info) + - 0*sizeof(struct netmsg_score_record); - netmsg_scores_info *return_info = malloc( data_size ); - - return_info->inetmsg_id = k_inetmsg_scores_info; - return_info->record_count = 0; - - SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( - hSteamNetworkingSockets, msg->m_conn, - return_info, data_size, - k_nSteamNetworkingSend_Reliable, NULL ); + + if( tmp->inetmsg_id == k_inetmsg_auth ) + on_inet_auth( msg ); + else if( tmp->inetmsg_id == k_inetmsg_scores_request ) + on_inet_score_request( msg ); + else if( tmp->inetmsg_id == k_inetmsg_set_nickname ) + on_inet_set_nickname( msg ); + else if( tmp->inetmsg_id == k_inetmsg_set_score ) + on_inet_set_score( msg ); + else { + vg_warn( "Unknown inetmsg_id recieved from client. (%u)\n", + tmp->inetmsg_id ); } SteamAPI_SteamNetworkingMessage_t_Release( msg ); @@ -142,11 +314,41 @@ static void poll_connections(void) } } +static u64 seconds_to_server_ticks( double s ) +{ + return s / 0.1; +} + +static void generate_boards(void) +{ + FILE *fp = fopen( "www/html/srhighscores.txt", "w" ); + + for( int i=0; idata, i, 10 ); + highscores_board_printf( fp, board->data, 10 ); + } + + fclose( fp ); +} + int main( int argc, char *argv[] ) { - steamworks_ensure_txt( "2103940" ); signal( SIGINT, inthandler ); + signal( SIGQUIT, inthandler ); + + /* TODO: Options to override, ammend, remove etc */ + vg_set_mem_quota( 80*1024*1024 ); + vg_alloc_quota(); + + highscores_init( 250000, 10000 ); + + if( !highscores_read() ) + highscores_create_db(); + + steamworks_ensure_txt( "2103940" ); if( !vg_load_steam_symetric_key( "application_key", steam_symetric_key ) ) return 0; @@ -192,18 +394,11 @@ int main( int argc, char *argv[] ) client_pollgroup = SteamAPI_ISteamNetworkingSockets_CreatePollGroup( hSteamNetworkingSockets ); -#if 0 - HTTPRequestHandle test_req = SteamAPI_ISteamHTTP_CreateHTTPRequest( - hSteamHTTP, k_EHTTPMethodGET, - "https://www.harrygodden.com/hello.txt" ); - - steam_async *call1 = steam_new_async(); - call1->data = NULL; - call1->p_handler = recieve_http; - SteamAPI_ISteamHTTP_SendHTTPRequest( hSteamHTTP, test_req, &call1->id ); -#endif + u64 server_ticks = 8000, + last_record_save = 8000, + last_scoreboard_gen = 0; - u64 server_ticks = 8000; + generate_boards(); while( !sig_stop ) { @@ -212,8 +407,22 @@ int main( int argc, char *argv[] ) usleep(100000); server_ticks ++; + + if(server_ticks > last_scoreboard_gen + seconds_to_server_ticks(1.0*60.0)) + { + last_scoreboard_gen = server_ticks; + generate_boards(); + } + + if(server_ticks > last_record_save + seconds_to_server_ticks( 10.0*60.0 )) + { + last_record_save = server_ticks; + highscores_serialize_all(); + } } + highscores_serialize_all(); + SteamAPI_ISteamNetworkingSockets_DestroyPollGroup( hSteamNetworkingSockets, client_pollgroup ); SteamAPI_ISteamNetworkingSockets_CloseListenSocket(