From b1f5771eda7a9788b86604a4368eb83babdf486d Mon Sep 17 00:00:00 2001 From: hgn Date: Sat, 30 Sep 2023 06:58:54 +0100 Subject: [PATCH] test network 2 --- gameserver.c | 172 ++++++++++++++++++++++++++++++++++-------------- gameserver.h | 1 + network.c | 83 ++++++++++++++++------- network.h | 5 +- network_msg.h | 14 +++- player_remote.c | 20 +++++- player_remote.h | 2 +- 7 files changed, 220 insertions(+), 77 deletions(-) diff --git a/gameserver.c b/gameserver.c index 8db3413..afc0bc3 100644 --- a/gameserver.c +++ b/gameserver.c @@ -34,43 +34,63 @@ static void set_connection_authsteamid(HSteamNetConnection con, u64_steamid id){ hSteamNetworkingSockets, con, userdata ); } -static void gameserver_player_join( int index ){ +static void gameserver_send_to_all( int ignore, + const void *pData, u32 cbData, + int nSendFlags ){ for( int i=0; iactive ) + if( (i==ignore) || !client->active ) continue; - netmsg_playerjoin join; - join.inetmsg_id = k_inetmsg_playerjoin; - join.index = index; - join.board_uid[0] = '\0'; - join.playermodel_uid[0] = '\0'; - join.username[0] = '\0'; - SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( hSteamNetworkingSockets, client->connection, - &join, sizeof(join), k_nSteamNetworkingSend_Reliable, NULL ); + pData, cbData, nSendFlags, NULL ); } } -static void gameserver_player_leave( int index ){ +static void gameserver_populate_join_msg( int index, netmsg_playerjoin *msg ){ + memset( msg, 0, sizeof(*msg) ); + msg->inetmsg_id = k_inetmsg_playerjoin; + msg->index = index; + vg_strncpy( gameserver.clients[index].username, msg->username, + sizeof(msg->username), k_strncpy_always_add_null ); +} + +static void gameserver_player_join( int index ){ + struct gameserver_client *joiner = &gameserver.clients[index]; + + netmsg_playerjoin join; + gameserver_populate_join_msg( index, &join ); + gameserver_send_to_all( index, &join, sizeof(join), + k_nSteamNetworkingSend_Reliable ); + + /* update the joining user about current connections */ for( int i=0; iactive ) continue; - netmsg_playerjoin leave; - leave.inetmsg_id = k_inetmsg_playerjoin; - leave.index = index; + netmsg_playerjoin init; + gameserver_populate_join_msg( i, &init ); SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( - hSteamNetworkingSockets, client->connection, - &leave, sizeof(leave), k_nSteamNetworkingSend_Reliable, NULL ); + hSteamNetworkingSockets, joiner->connection, + &join, sizeof(join), k_nSteamNetworkingSend_Reliable, NULL ); } } +static void gameserver_player_leave( int index ){ + + netmsg_playerjoin leave; + leave.inetmsg_id = k_inetmsg_playerleave; + leave.index = index; + + gameserver_send_to_all( index, &leave, sizeof(leave), + k_nSteamNetworkingSend_Reliable ); +} + static void new_client_connecting( HSteamNetConnection client ){ int index = -1; @@ -125,6 +145,19 @@ static void on_auth_status( CallbackMsg_t *msg ){ vg_info( " %s\n", info->m_debugMsg ); } +static int gameserver_client_index( HSteamNetConnection hconn ){ + for( int i=0; iactive ){ + if( client->connection == hconn ){ + return i; + } + } + } + return -1; +} + static void on_connect_status( CallbackMsg_t *msg ){ SteamNetConnectionStatusChangedCallback_t *info = (void *)msg->m_pubParam; vg_info( " Connection status changed for %lu\n", info->m_hConn ); @@ -142,17 +175,12 @@ static void on_connect_status( CallbackMsg_t *msg ){ (info->m_info.m_eState == k_ESteamNetworkingConnectionState_ProblemDetectedLocally ) ){ - for( int i=0; iactive ){ - if( client->connection == info->m_hConn ){ - client->connection = 0; - client->active = 0; - gameserver_player_leave(i); - break; - } - } + int client_id = gameserver_client_index( info->m_hConn ); + if( client_id != -1 ){ + struct gameserver_client *client = &gameserver.clients[client_id]; + client->connection = 0; + client->active = 0; + gameserver_player_leave(client_id); } vg_info( "End reason: %d\n", info->m_info.m_eEndReason ); @@ -161,7 +189,7 @@ static void on_connect_status( CallbackMsg_t *msg ){ } } -static void on_inet_auth( SteamNetworkingMessage_t *msg ){ +static void gameserver_rx_auth( SteamNetworkingMessage_t *msg ){ if( gameserver.auth_mode != eServerModeAuthentication ){ vg_error( "Running server without authentication. " "Connection %u tried to authenticate.\n", msg->m_conn ); @@ -250,6 +278,51 @@ static int inet_require_auth( SteamNetworkingMessage_t *msg ){ else return 1; } +/* + * Player updates sent to us + * ----------------------------------------------------------------------------- + */ + +static int packet_minsize( SteamNetworkingMessage_t *msg, u32 size ){ + if( msg->m_cbSize < size ) { + vg_error( "Invalid packet size (must be at least %u)\n", size ); + return 0; + } + else{ + return 1; + } +} + +static void gameserver_rx_200_300( SteamNetworkingMessage_t *msg ){ + netmsg_blank *tmp = msg->m_pData; + + if( tmp->inetmsg_id == k_inetmsg_playerusername ){ + if( !packet_minsize( msg, sizeof(netmsg_playerusername) )) + return; + + int client_id = gameserver_client_index( msg->m_conn ); + if( client_id != -1 ){ + struct gameserver_client *client = &gameserver.clients[ client_id ]; + netmsg_playerusername *src = msg->m_pData; + + vg_strncpy( src->username, client->username, sizeof(client->username), + k_strncpy_always_add_null ); + + /* update other users about this change */ + netmsg_playerusername msg; + memset( &msg, 0, sizeof(msg) ); + msg.inetmsg_id = k_inetmsg_playerusername; + msg.index = client_id; + vg_strncpy( client->username, msg.username, sizeof(msg.username), + k_strncpy_always_add_null ); + + gameserver_send_to_all( client_id, &msg, sizeof(msg), + k_nSteamNetworkingSend_Reliable ); + } + } +} + +#if 0 static void on_inet_score_request( SteamNetworkingMessage_t *msg ){ if( !inet_require_auth(msg) ) return; @@ -304,14 +377,7 @@ static void on_inet_set_score( SteamNetworkingMessage_t *msg ){ highscores_push_record( &temp ); } } - -static void on_inet_playerframe( SteamNetworkingMessage_t *msg ){ - if( msg->m_cbSize < sizeof(netmsg_playerframe) ){ - return; - } - - netmsg_playerframe *info = msg->m_pData; -} +#endif static void poll_connections(void){ SteamNetworkingMessage_t *messages[32]; @@ -336,20 +402,28 @@ static void poll_connections(void){ netmsg_blank *tmp = msg->m_pData; - 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 if( tmp->inetmsg_id == k_inetmsg_playerframe ) - on_inet_playerframe( msg ); - else { - vg_warn( "Unknown inetmsg_id recieved from client. (%u)\n", - tmp->inetmsg_id ); + if( (tmp->inetmsg_id >= 200) && (tmp->inetmsg_id < 300) ){ + gameserver_rx_200_300( msg ); } + else{ + if( tmp->inetmsg_id == k_inetmsg_auth ) + gameserver_rx_auth( msg ); +#if 0 + 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 if( tmp->inetmsg_id == k_inetmsg_playerframe ) + on_inet_playerframe( msg ); +#endif + else { + vg_warn( "Unknown inetmsg_id recieved from client. (%u)\n", + tmp->inetmsg_id ); + } + } + SteamAPI_SteamNetworkingMessage_t_Release( msg ); } diff --git a/gameserver.h b/gameserver.h index a1b5d6a..092f0b5 100644 --- a/gameserver.h +++ b/gameserver.h @@ -19,6 +19,7 @@ struct { int active; int authenticated; HSteamNetConnection connection; + char username[32]; } clients[ 32 ]; diff --git a/network.c b/network.c index 777fab4..8b34fb0 100644 --- a/network.c +++ b/network.c @@ -5,6 +5,16 @@ static void scores_update(void); +static int packet_minsize( SteamNetworkingMessage_t *msg, u32 size ){ + if( msg->m_cbSize < size ) { + vg_error( "Invalid packet size (must be at least %u)\n", size ); + return 0; + } + else{ + return 1; + } +} + static void on_auth_ticket_recieved( void *result, void *context ){ EncryptedAppTicketResponse_t *response = result; @@ -43,20 +53,7 @@ static void request_auth_ticket(void){ SteamAPI_ISteamUser_RequestEncryptedAppTicket( hSteamUser, NULL, 0 ); } -static void send_auth_ticket(void){ - u32 size = sizeof(netmsg_auth) + network_client.app_key_length; - netmsg_auth *auth = alloca(size); - - auth->inetmsg_id = k_inetmsg_auth; - auth->ticket_length = network_client.app_key_length; - for( int i=0; iticket[i] = network_client.app_symmetric_key[i]; - - SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( - hSteamNetworkingSockets, network_client.remote, auth, size, - k_nSteamNetworkingSend_Reliable, NULL ); -} - +#if 0 static void send_score_request(void){ vg_info( "Requesting scores\n" ); netmsg_scores_request req; @@ -124,6 +121,7 @@ static void send_nickname(void){ network_client.name_update = 0; } +#endif static void network_send_playerframe(void){ netmsg_playerframe frame; @@ -136,13 +134,28 @@ static void network_send_playerframe(void){ k_nSteamNetworkingSend_Unreliable, NULL ); } +#if 0 static void server_routine_update(void){ - if( network_client.name_update ) - send_nickname(); - send_score_update(); send_score_request(); } +#endif + +static void network_send_username(void){ + netmsg_playerusername update; + memset( &update, 0, sizeof(update) ); + update.inetmsg_id = k_inetmsg_playerusername; + update.index = 0xffffffff; + + ISteamFriends *hSteamFriends = SteamAPI_SteamFriends(); + const char *username = SteamAPI_ISteamFriends_GetPersonaName(hSteamFriends); + str_utf8_collapse( username, update.username, sizeof(update.username) ); + + SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( + hSteamNetworkingSockets, network_client.remote, + &update, sizeof(update), + k_nSteamNetworkingSend_Reliable, NULL ); +} static void on_server_connect_status( CallbackMsg_t *msg ){ SteamNetConnectionStatusChangedCallback_t *info = (void *)msg->m_pubParam; @@ -157,7 +170,21 @@ static void on_server_connect_status( CallbackMsg_t *msg ){ if( info->m_info.m_eState == k_ESteamNetworkingConnectionState_Connected ){ vg_success(" Connected to remote server.. authenticating\n"); - send_auth_ticket(); + + /* TODO: We should really wait to see if the server is in auth mode + * first... */ + u32 size = sizeof(netmsg_auth) + network_client.app_key_length; + netmsg_auth *auth = alloca(size); + auth->inetmsg_id = k_inetmsg_auth; + auth->ticket_length = network_client.app_key_length; + for( int i=0; iticket[i] = network_client.app_symmetric_key[i]; + + SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( + hSteamNetworkingSockets, network_client.remote, auth, size, + k_nSteamNetworkingSend_Reliable, NULL ); + + network_send_username(); } else if( info->m_info.m_eState == k_ESteamNetworkingConnectionState_ClosedByPeer ){ @@ -183,6 +210,19 @@ static void on_server_connect_status( CallbackMsg_t *msg ){ } } +static void on_persona_state_change( CallbackMsg_t *msg ){ + if( network_client.remote ){ + PersonaStateChange_t *info = (void *)msg->m_pubParam; + + ISteamUser *hSteamUser = SteamAPI_SteamUser(); + if( info->m_ulSteamID == SteamAPI_ISteamUser_GetSteamID(hSteamUser) ){ + if( info->m_nChangeFlags == k_EPersonaChangeNickname ){ + network_send_username(); + } + } + } +} + static void network_connect(void){ /* Connect to server if not connected */ SteamNetworkingIPAddr remoteAddr; @@ -258,11 +298,8 @@ static void poll_remote_connection(void){ netmsg_blank *tmp = msg->m_pData; - if( tmp->inetmsg_id == k_inetmsg_scoreboard ) - on_inet_scoreboard( msg ); - if( (tmp->inetmsg_id >= 200) && (tmp->inetmsg_id < 300) ){ - player_remote_packet( msg ); + player_remote_rx_200_300( msg ); } SteamAPI_SteamNetworkingMessage_t_Release( msg ); @@ -313,6 +350,8 @@ static void network_init(void){ if( steam_ready ){ steam_register_callback( k_iSteamNetConnectionStatusChangedCallBack, on_server_connect_status ); + steam_register_callback( k_iPersonaStateChange, + on_persona_state_change ); request_auth_ticket(); } } diff --git a/network.h b/network.h index 066b9f8..bb019fb 100644 --- a/network.h +++ b/network.h @@ -42,8 +42,6 @@ struct { u8 app_symmetric_key[ 1024 ]; u32 app_key_length; EServerMode auth_mode; - - int name_update; HSteamNetConnection remote; ESteamNetworkingConnectionState state; @@ -56,7 +54,8 @@ struct { static network_client = { .state = k_ESteamNetworkingConnectionState_None, .auth_mode = eServerModeAuthentication, - .name_update = 1 }; +static int packet_minsize( SteamNetworkingMessage_t *msg, u32 size ); + #endif /* NETWORK_H */ diff --git a/network_msg.h b/network_msg.h index 9ad5c87..0d585ba 100644 --- a/network_msg.h +++ b/network_msg.h @@ -87,14 +87,15 @@ static scoreboard_client_data = { /* player updates 200 */ +/* client -> remote */ typedef struct netmsg_playerframe netmsg_playerframe; enum{ k_inetmsg_playerframe = 200 }; struct netmsg_playerframe{ u32 inetmsg_id; - v3f pos_temp; }; +/* remote -> client */ typedef struct netmsg_playerjoin netmsg_playerjoin; enum{ k_inetmsg_playerjoin = 201 }; struct netmsg_playerjoin{ @@ -106,6 +107,8 @@ struct netmsg_playerjoin{ char board_uid[76]; /* UNUSED */ }; + +/* remote -> client */ typedef struct netmsg_playerleave netmsg_playerleave; enum{ k_inetmsg_playerleave = 202 }; struct netmsg_playerleave{ @@ -113,5 +116,14 @@ struct netmsg_playerleave{ u32 index; }; +/* client <-> remote */ +typedef struct netmsg_playerusername netmsg_playerusername; +enum{ k_inetmsg_playerusername = 203 }; +struct netmsg_playerusername{ + u32 inetmsg_id; + u32 index; + char username[32]; +}; + #pragma pack(pop) #endif /* NETWORK_MSG_H */ diff --git a/player_remote.c b/player_remote.c index d9ee7b8..6063379 100644 --- a/player_remote.c +++ b/player_remote.c @@ -12,11 +12,12 @@ static void player_remote_clear( struct network_player *player ){ player->subsystem = k_player_subsystem_invalid; } -static void player_remote_packet( SteamNetworkingMessage_t *msg ){ +static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ){ netmsg_blank *tmp = msg->m_pData; if( tmp->inetmsg_id == k_inetmsg_playerjoin ){ netmsg_playerjoin *playerjoin = msg->m_pData; + if( !packet_minsize( msg, sizeof(*playerjoin) )) return; if( playerjoin->index < vg_list_size(netplayers.list) ){ struct network_player *player = &netplayers.list[ playerjoin->index ]; @@ -33,6 +34,7 @@ static void player_remote_packet( SteamNetworkingMessage_t *msg ){ } else if( tmp->inetmsg_id == k_inetmsg_playerleave ){ netmsg_playerleave *playerleave = msg->m_pData; + if( !packet_minsize( msg, sizeof(*playerleave) )) return; if( playerleave->index < vg_list_size(netplayers.list) ){ struct network_player *player = &netplayers.list[ playerleave->index ]; @@ -43,6 +45,21 @@ static void player_remote_packet( SteamNetworkingMessage_t *msg ){ vg_error( "inetmsg_playerleave: player index out of range\n" ); } } + else if( tmp->inetmsg_id == k_inetmsg_playerusername ){ + netmsg_playerusername *update = msg->m_pData; + if( !packet_minsize( msg, sizeof(*update) )) return; + + if( update->index < vg_list_size(netplayers.list) ){ + struct network_player *player = &netplayers.list[ update->index ]; + vg_strncpy( update->username, player->username, + sizeof(player->username), k_strncpy_always_add_null ); + + vg_info( "#%u changed username: %s\n", player->username ); + } + else { + vg_error( "inetmsg_playerleave: player index out of range\n" ); + } + } } static void remote_player_network_imgui(void){ @@ -77,6 +94,7 @@ static void remote_player_network_imgui(void){ snprintf( buf, 512, "Network: %s", netstatus ); ui_info( panel, buf ); ui_info( panel, "---------------------" ); + ui_info( panel, "#-1: localplayer" ); for( u32 i=0; i