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;
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 );
(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 );
}
}
-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 );
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;
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];
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 );
}
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;
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;
network_client.name_update = 0;
}
+#endif
static void network_send_playerframe(void){
netmsg_playerframe frame;
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;
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 ){
}
}
+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;
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 );
if( steam_ready ){
steam_register_callback( k_iSteamNetConnectionStatusChangedCallBack,
on_server_connect_status );
+ steam_register_callback( k_iPersonaStateChange,
+ on_persona_state_change );
request_auth_ticket();
}
}
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 ];
}
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 ];
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){
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];