test network 2
authorhgn <hgodden00@gmail.com>
Sat, 30 Sep 2023 05:58:54 +0000 (06:58 +0100)
committerhgn <hgodden00@gmail.com>
Sat, 30 Sep 2023 05:58:54 +0000 (06:58 +0100)
gameserver.c
gameserver.h
network.c
network.h
network_msg.h
player_remote.c
player_remote.h

index 8db34132f61adb0ebc5386bfcbe40492cc9a25ef..afc0bc31a00743c840ecd2f7c354356cf016e847 100644 (file)
@@ -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; i<vg_list_size(gameserver.clients); i++ ){
       struct gameserver_client *client = &gameserver.clients[i];
 
-      if( (i==index) || !client->active )
+      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; i<vg_list_size(gameserver.clients); i++ ){
       struct gameserver_client *client = &gameserver.clients[i];
 
       if( (i==index) || !client->active )
          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; i<vg_list_size(gameserver.clients); i++ ){
+      struct gameserver_client *client = &gameserver.clients[i];
+
+      if( client->active ){
+         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; i<vg_list_size(gameserver.clients); i++ ){
-         struct gameserver_client *client = &gameserver.clients[i];
-
-         if( client->active ){
-            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 );
       }
index a1b5d6ae0b2d5a64b7c3b18a1495e1f052e7372d..092f0b5d99dff3a913dcdaeb0785b1da1dd5d294 100644 (file)
@@ -19,6 +19,7 @@ struct {
       int active;
       int authenticated;
       HSteamNetConnection connection;
+      char username[32];
    }
    clients[ 32 ];
 
index 777fab46b9852e72c1ab8568653a807208ce03e4..8b34fb092a9668a820dc662e2d20846769af77e7 100644 (file)
--- 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; i<network_client.app_key_length; i++ )
-      auth->ticket[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; i<network_client.app_key_length; i++ )
+            auth->ticket[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();
    }
 }
index 066b9f82f3e1bc245ce3a3fbe63fa6a3331ec03c..bb019fb7b9e39bb3ec0683d9bcaa3b191e58ae0e 100644 (file)
--- 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 */
index 9ad5c878420eedd22c694e9da5ff331cc01222aa..0d585badcfd7b4b89e27a50f4ed7a2b0e9585d62 100644 (file)
@@ -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 */
index d9ee7b8243a8f95e190add9c2075dc802ec160d9..606337987948e4aafb5a8ef25f2bdb7172e4ffa7 100644 (file)
@@ -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<vg_list_size(netplayers.list); i++ ){
       struct network_player *player = &netplayers.list[i];
index bd5f6ddafdd61831753486100ab44da071b3c6cf..e2d757c31a2c6b3ecbb668e3bebf2b5bdeaab554 100644 (file)
@@ -23,6 +23,6 @@ struct {
 }
 static netplayers;
 
-static void player_remote_packet( SteamNetworkingMessage_t *msg );
+static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg );
 
 #endif /* PLAYER_REMOTE_H */