test network 1
authorhgn <hgodden00@gmail.com>
Fri, 29 Sep 2023 16:26:02 +0000 (17:26 +0100)
committerhgn <hgodden00@gmail.com>
Fri, 29 Sep 2023 16:26:02 +0000 (17:26 +0100)
13 files changed:
gameserver.c
gameserver.h
network.c
network.h
network_msg.h
player.h
player_dead.h
player_drive.h
player_remote.c [new file with mode: 0644]
player_remote.h [new file with mode: 0644]
player_skate.h
player_walk.h
skaterift.c

index c63711ab30883f6cfcea0d17f09e2f5b611635f7..8db34132f61adb0ebc5386bfcbe40492cc9a25ef 100644 (file)
@@ -34,21 +34,87 @@ static void set_connection_authsteamid(HSteamNetConnection con, u64_steamid id){
          hSteamNetworkingSockets, con, userdata );
 }
 
+static void gameserver_player_join( int index ){
+   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 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 );
+   }
+}
+
+static void gameserver_player_leave( int index ){
+   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;
+
+      SteamAPI_ISteamNetworkingSockets_SendMessageToConnection(
+            hSteamNetworkingSockets, client->connection,
+            &leave, sizeof(leave), k_nSteamNetworkingSend_Reliable, NULL );
+   }
+}
+
 static void new_client_connecting( HSteamNetConnection client ){
+   int index = -1;
+
+   /* TODO: LRU */
+   for( int i=0; i<vg_list_size(gameserver.clients); i++ ){
+      if( !gameserver.clients[i].active ){
+         index = i;
+         break;
+      }
+   }
+
+   if( index == -1 ){
+      vg_error( "Server full\n" );
+      SteamAPI_ISteamNetworkingSockets_CloseConnection( 
+            hSteamNetworkingSockets, client, 
+            4500,
+            NULL, 1 );
+      return;
+   }
+
    EResult accept_status = SteamAPI_ISteamNetworkingSockets_AcceptConnection(
             hSteamNetworkingSockets, client );
-
    if( accept_status == k_EResultOK ){
-      vg_success( "Accepted client (id: %u)\n", client );
+      vg_success( "Accepted client (id: %u, index: %d)\n", client, index );
+
+      gameserver.clients[index].active = 1;
+      gameserver.clients[index].connection = client;
+
       SteamAPI_ISteamNetworkingSockets_SetConnectionPollGroup(
             hSteamNetworkingSockets,
             client, gameserver.client_group );
       
       /* Just to be sure */
       set_connection_authsteamid( client, -1 );
+      gameserver_player_join( index );
    }
    else{
       vg_warn( "Error accepting client (id: %u)\n", client );
+      SteamAPI_ISteamNetworkingSockets_CloseConnection( 
+            hSteamNetworkingSockets, client, 
+            k_ESteamNetConnectionEnd_Misc_InternalError,
+            NULL, 1 );
+      gameserver.clients[index].active = 0;
+      gameserver.clients[index].connection = 0;
    }
 }
 
@@ -70,6 +136,29 @@ static void on_connect_status( CallbackMsg_t *msg ){
    if( info->m_info.m_eState==k_ESteamNetworkingConnectionState_Connecting ){
       new_client_connecting( info->m_hConn );
    }
+
+   if( (info->m_info.m_eState == 
+            k_ESteamNetworkingConnectionState_ClosedByPeer ) ||
+       (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;
+            }
+         }
+      }
+
+      vg_info( "End reason: %d\n", info->m_info.m_eEndReason );
+      SteamAPI_ISteamNetworkingSockets_CloseConnection( 
+            hSteamNetworkingSockets, info->m_hConn, 0, NULL, 0 );
+   }
 }
 
 static void on_inet_auth( SteamNetworkingMessage_t *msg ){
@@ -150,7 +239,7 @@ 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 );
+               msg->m_conn );
 
       SteamAPI_ISteamNetworkingSockets_CloseConnection(
             hSteamNetworkingSockets,
@@ -221,11 +310,7 @@ static void on_inet_playerframe( SteamNetworkingMessage_t *msg ){
       return;
    }
 
-
    netmsg_playerframe *info = msg->m_pData;
-   vg_info( "... @: %.2f %.2f %.2f\n", 
-               //msg->m_identityPeer,
-               info->pos_temp[0], info->pos_temp[1], info->pos_temp[2] );
 }
 
 static void poll_connections(void){
index 670a9ba089be4debe5a46160d33b0ee6875b934f..a1b5d6ae0b2d5a64b7c3b18a1495e1f052e7372d 100644 (file)
@@ -15,6 +15,13 @@ struct {
    HSteamNetPollGroup client_group;
    EServerMode auth_mode;
 
+   struct gameserver_client {
+      int active;
+      int authenticated;
+      HSteamNetConnection connection;
+   }
+   clients[ 32 ];
+
    u8 app_symmetric_key[ k_nSteamEncryptedAppTicketSymmetricKeyLen ];
 
    int monitor_fd;
index 63b70c3903feea369c927fae63b7eef9c7f92741..777fab46b9852e72c1ab8568653a807208ce03e4 100644 (file)
--- a/network.c
+++ b/network.c
@@ -1,5 +1,7 @@
 #include "player.h"
 #include "network.h"
+#include "network_msg.h"
+#include "player_remote.h"
 
 static void scores_update(void);
 
@@ -151,13 +153,33 @@ static void on_server_connect_status( CallbackMsg_t *msg ){
 
    if( info->m_hConn == network_client.remote ){
       network_client.state = info->m_info.m_eState;
-      if( info->m_info.m_eState == k_ESteamNetworkingConnectionState_Connected ){
+
+      if( info->m_info.m_eState == 
+            k_ESteamNetworkingConnectionState_Connected ){
          vg_success("  Connected to remote server.. authenticating\n");
          send_auth_ticket();
       }
+      else if( info->m_info.m_eState == 
+            k_ESteamNetworkingConnectionState_ClosedByPeer ){
+
+         if( info->m_info.m_eEndReason == 
+               k_ESteamNetConnectionEnd_Remote_Max ){
+            network_client.retries = 40;
+         }
+
+         SteamAPI_ISteamNetworkingSockets_CloseConnection( 
+               hSteamNetworkingSockets, info->m_hConn, 0, NULL, 0 );
+         network_client.remote = 0;
+      }
+      else if( info->m_info.m_eState == 
+            k_ESteamNetworkingConnectionState_ProblemDetectedLocally ){
+         SteamAPI_ISteamNetworkingSockets_CloseConnection( 
+               hSteamNetworkingSockets, info->m_hConn, 0, NULL, 0 );
+         network_client.remote = 0;
+      }
    }
    else{
-      vg_warn( "  Recieved signal from unknown connection\n" );
+      //vg_warn( "  Recieved signal from unknown connection\n" );
    }
 }
 
@@ -205,9 +227,11 @@ static void on_inet_scoreboard( SteamNetworkingMessage_t *msg ){
       }
    }
 
+#if 0
    /* We dont need to stay on the server currently */
    SteamAPI_ISteamNetworkingSockets_CloseConnection(
          hSteamNetworkingSockets, network_client.remote, 0, NULL, 1 );
+#endif
 
    network_scores_updated = 1;
 }
@@ -237,6 +261,10 @@ static void poll_remote_connection(void){
          if( tmp->inetmsg_id == k_inetmsg_scoreboard )
             on_inet_scoreboard( msg );
 
+         if( (tmp->inetmsg_id >= 200) && (tmp->inetmsg_id < 300) ){
+            player_remote_packet( msg );
+         }
+
          SteamAPI_SteamNetworkingMessage_t_Release( msg );
       }
    }
@@ -280,6 +308,8 @@ static void network_update(void){
 }
 
 static void network_init(void){
+   vg_console_reg_var( "network_info", &network_client.network_info,
+                       k_var_dtype_i32, VG_VAR_PERSISTENT );
    if( steam_ready ){
       steam_register_callback( k_iSteamNetConnectionStatusChangedCallBack,
                                on_server_connect_status );
index 16594e84184c1f01ad8519142d7f48fca77986c2..066b9f82f3e1bc245ce3a3fbe63fa6a3331ec03c 100644 (file)
--- a/network.h
+++ b/network.h
@@ -50,6 +50,8 @@ struct {
 
    f64 last_attempt, last_frame;
    u32 retries;
+
+   i32 network_info;
 }
 static network_client = {
    .state = k_ESteamNetworkingConnectionState_None,
index 495f4ae4727bfc27ce57eaa168d6f6cb02202fe2..9ad5c878420eedd22c694e9da5ff331cc01222aa 100644 (file)
@@ -8,6 +8,7 @@
 #include "vg/vg_stdint.h"
 #include "world_info.h"
 #include "vg/vg_platform.h"
+;
 
 #pragma pack(push,1)
 
@@ -81,13 +82,36 @@ static scoreboard_client_data = {
 }; 
 /* probably about 10k */
 
+/* server control 100 */
+
+
+/* player updates 200 */
+
 typedef struct netmsg_playerframe netmsg_playerframe;
-enum{ k_inetmsg_playerframe = 20 };
+enum{ k_inetmsg_playerframe = 200 };
 struct netmsg_playerframe{
    u32 inetmsg_id;
 
    v3f pos_temp;
 };
 
+typedef struct netmsg_playerjoin netmsg_playerjoin;
+enum{ k_inetmsg_playerjoin = 201 };
+struct netmsg_playerjoin{
+   u32 inetmsg_id;
+
+   u32 index;
+   char username[32];         /* UNUSED */
+   char playermodel_uid[76];  /* UNUSED */
+   char board_uid[76];        /* UNUSED */
+};
+
+typedef struct netmsg_playerleave netmsg_playerleave;
+enum{ k_inetmsg_playerleave = 202 };
+struct netmsg_playerleave{
+   u32 inetmsg_id;
+   u32 index;
+};
+
 #pragma pack(pop)
 #endif /* NETWORK_MSG_H */
index dedae18a78f55178f391f35492633f7b1679b304..36b37a9f4a78160e0e4e79f4e4c521be36a68724 100644 (file)
--- a/player.h
+++ b/player.h
@@ -5,10 +5,12 @@
 #include "player_common.h"
 
 enum player_subsystem{
+   k_player_subsystem_invalid = -1,
    k_player_subsystem_walk = 0,
    k_player_subsystem_skate = 1,
    k_player_subsystem_dead = 2,
-   k_player_subsystem_drive = 3
+   k_player_subsystem_drive = 3,
+   k_player_subsystem_max
 };
 
 struct player_cam_controller {
@@ -44,6 +46,8 @@ struct player_subsystem_interface{
 
    void *animator_data;
    u32 animator_size;
+
+   const char *name;
 };
 
 #include "player_ragdoll.h"
index 03c932602af117314cc41b31b92d03cb44163a12..0c1de4133872c51800fcdf7a9b175fcf3cf796c9 100644 (file)
@@ -35,7 +35,8 @@ struct player_subsystem_interface static player_subsystem_dead = {
    .im_gui = player__dead_im_gui,
 
    .animator_data = &player_dead.animator,
-   .animator_size = sizeof(player_dead.animator)
+   .animator_size = sizeof(player_dead.animator),
+   .name = "Dead"
 };
 
 #endif /* PLAYER_DEAD_H */
index 071fef478c41db6504e3804168b3fc38d7457a87..46eedba48860cf2eaa584e85aeb12bf8749df216 100644 (file)
@@ -33,7 +33,8 @@ struct player_subsystem_interface static player_subsystem_drive = {
    .reset = player__drive_reset,
 
    .animator_data = NULL,
-   .animator_size = 0
+   .animator_size = 0,
+   .name = "Drive"
 };
 
 #endif /* PLAYER_DRIVE_H */
diff --git a/player_remote.c b/player_remote.c
new file mode 100644 (file)
index 0000000..d9ee7b8
--- /dev/null
@@ -0,0 +1,94 @@
+#include "player_remote.h"
+
+static void player_remote_unwatch( struct network_player *player ){
+   addon_cache_unwatch( k_addon_type_player, player->playermodel_view_slot );
+   addon_cache_unwatch( k_addon_type_board, player->board_view_slot );
+}
+
+static void player_remote_clear( struct network_player *player ){
+   player_remote_unwatch( player );
+   memset( player, 0, sizeof(*player) );
+   strcpy( player->username, "unknown" );
+   player->subsystem = k_player_subsystem_invalid;
+}
+
+static void player_remote_packet( SteamNetworkingMessage_t *msg ){
+   netmsg_blank *tmp = msg->m_pData;
+
+   if( tmp->inetmsg_id == k_inetmsg_playerjoin ){
+      netmsg_playerjoin *playerjoin = msg->m_pData;
+
+      if( playerjoin->index < vg_list_size(netplayers.list) ){
+         struct network_player *player = &netplayers.list[ playerjoin->index ];
+         player_remote_clear( player );
+         player->active = 1;
+
+         /* TODO: interpret the uids */
+         player->board_view_slot = 0;
+         player->playermodel_view_slot = 0;
+      }
+      else {
+         vg_error( "inetmsg_playerjoin: player index out of range\n" );
+      }
+   }
+   else if( tmp->inetmsg_id == k_inetmsg_playerleave ){
+      netmsg_playerleave *playerleave = msg->m_pData;
+      
+      if( playerleave->index < vg_list_size(netplayers.list) ){
+         struct network_player *player = &netplayers.list[ playerleave->index ];
+         player_remote_unwatch( player );
+         player->active = 0;
+      }
+      else {
+         vg_error( "inetmsg_playerleave: player index out of range\n" );
+      }
+   }
+}
+
+static void remote_player_network_imgui(void){
+   if( !network_client.network_info ) 
+      return;
+
+   ui_rect panel = { (vg.window_x / 2) - 200, 0, 400, 600 };
+   ui_fill( panel, (ui_colour(k_ui_bg)&0x00ffffff)|0x50000000 );
+
+   char buf[512];
+   const char *netstatus = "PROGRAMMING ERROR";
+
+   struct { enum ESteamNetworkingConnectionState state; const char *str; }
+   states[] = {
+          { k_ESteamNetworkingConnectionState_None, "None" },
+          { k_ESteamNetworkingConnectionState_Connecting, "Connecting" },
+          { k_ESteamNetworkingConnectionState_FindingRoute, "Finding Route" },
+          { k_ESteamNetworkingConnectionState_Connected, "Connected" },
+          { k_ESteamNetworkingConnectionState_ClosedByPeer, "Closed by peer" },
+          { k_ESteamNetworkingConnectionState_ProblemDetectedLocally, 
+         "Problem Detected Locally" },
+          { k_ESteamNetworkingConnectionState_FinWait, "Fin Wait" },
+          { k_ESteamNetworkingConnectionState_Linger, "Linger" },
+          { k_ESteamNetworkingConnectionState_Dead, "Dead" }
+   };
+   for( u32 i=0; i<vg_list_size(states); i ++ ){
+      if( states[i].state == network_client.state ){
+         netstatus = states[i].str;
+         break;
+      }
+   }
+   snprintf( buf, 512, "Network: %s", netstatus );
+   ui_info( panel, buf );
+   ui_info( panel, "---------------------" );
+
+   for( u32 i=0; i<vg_list_size(netplayers.list); i++ ){
+      struct network_player *player = &netplayers.list[i];
+      if( player->active ){
+         const char *sysname = "invalid";
+
+         if( (player->subsystem >= 0) && 
+             (player->subsystem < k_player_subsystem_max) ){
+            sysname = player_subsystems[ player->subsystem ]->name;
+         }
+         snprintf( buf, 512, "#%u: %s [%s]", i, player->username, sysname );
+         ui_info( panel, buf );
+      }
+   }
+}
diff --git a/player_remote.h b/player_remote.h
new file mode 100644 (file)
index 0000000..bd5f6dd
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef PLAYER_REMOTE_H
+#define PLAYER_REMOTE_H
+
+#include "player.h"
+#include "network.h"
+
+struct {
+   struct network_player {
+      int active;
+      u16 board_view_slot, playermodel_view_slot;
+      player_pose pose;
+
+      char username[32];
+
+      enum player_subsystem subsystem;
+      union {
+         struct player_skate_animator _skate;
+         struct player_walk_animator _walk;
+         struct player_dead_animator _dead;
+      };
+   }
+   list[ 32 ];
+}
+static netplayers;
+
+static void player_remote_packet( SteamNetworkingMessage_t *msg );
+
+#endif /* PLAYER_REMOTE_H */
index 6dbb897872cf906e7118c1517ddbf1a7dbb70bec..68f2dcb9980c06f7c0c2a3ba78c84051a5a73225 100644 (file)
@@ -305,7 +305,8 @@ struct player_subsystem_interface static player_subsystem_skate = {
    .post_animate = player__skate_post_animate,
 
    .animator_data = &player_skate.animator,
-   .animator_size = sizeof(player_skate.animator)
+   .animator_size = sizeof(player_skate.animator),
+   .name = "Skate"
 };
 
 #endif /* PLAYER_SKATE_H */
index ae0f9c36f77624f466854893efe92db0789ba9c4..14acb703c74d0d4685f64ae00c636cca146cea9e 100644 (file)
@@ -112,7 +112,8 @@ struct player_subsystem_interface static player_subsystem_walk = {
    .pose = player__walk_pose,
 
    .animator_data = &player_walk.animator,
-   .animator_size = sizeof(player_walk.animator)
+   .animator_size = sizeof(player_walk.animator),
+   .name = "Walk"
 };
 
 #endif /* PLAYER_WALK_H */
index 14c64101a275512615d77b740463fa6c64c969cf..7f384f63780f276d71178e17cb8d001a638e2f7f 100644 (file)
@@ -39,6 +39,7 @@
 #include "vehicle.h"
 #include "pointcloud.h"
 #include "save.h"
+#include "player_remote.h"
 
 /*    unity build
  * ----------------- */
@@ -53,6 +54,7 @@
 #include "save.c"
 #include "respawn.c"
 #include "network.c"
+#include "player_remote.c"
 
 static struct player_avatar localplayer_avatar;
 
@@ -634,6 +636,7 @@ static void vg_gui(void){
    skaterift_replay_imgui();
    workshop_form_gui();
    render_view_framebuffer_ui();
+   remote_player_network_imgui();
 }