From 825c3bce18272c0f81659e0eac469709d0462836 Mon Sep 17 00:00:00 2001 From: hgn Date: Sun, 1 Oct 2023 04:18:34 +0100 Subject: [PATCH 1/1] refactor network packets --- addon.c | 56 +++++++++++++++++++++++++++- addon.h | 18 ++++++--- gameserver.c | 66 ++++++++++++++++++-------------- gameserver.h | 3 +- network.c | 13 ++++--- network_common.h | 21 +++++++++++ network_msg.h | 20 +++++----- player_remote.c | 97 ++++++++++++++++++++++++++++++++---------------- player_render.c | 36 ++++++++++-------- player_render.h | 2 + skaterift.c | 35 ----------------- steam.h | 6 +-- 12 files changed, 237 insertions(+), 136 deletions(-) create mode 100644 network_common.h diff --git a/addon.c b/addon.c index 7e03050..c387edd 100644 --- a/addon.c +++ b/addon.c @@ -69,7 +69,10 @@ static u32 addon_match( addon_alias *alias ){ return 0xffffffff; } -static void addon_alias_uid( addon_alias *alias, char buf[76] ){ +/* + * Create a string version of addon alias in buf + */ +static void addon_alias_uid( addon_alias *alias, char buf[ADDON_UID_MAX] ){ if( alias->workshop_id ){ snprintf( buf, 128, "sr%03d-steam-"PRINTF_U64, alias->type, alias->workshop_id ); @@ -80,6 +83,40 @@ static void addon_alias_uid( addon_alias *alias, char buf[76] ){ } } +/* + * parse uid to alias. returns 1 if successful + */ +static int addon_uid_to_alias( char uid[ADDON_UID_MAX], addon_alias *alias ){ +/* 1 + * 01234567890123 + * sr&&&-@@@@@-#* + * | | | + * type | id + * | + * location + */ + if( strlen(uid) < 13 ) return 0; + if( !((uid[0] == 's') && (uid[1] == 'r')) ) return 0; + + char type[4]; + memcpy( type, uid+2, 3 ); + type[3] = '\0'; + alias->type = atoi(type); + + char location[6]; + memcpy( location, uid+6, 5 ); + location[5] = '\0'; + + if( !strcmp(location,"steam") ) + alias->workshop_id = atoll( uid+12 ); + else if( !strcmp(location,"local") ) + vg_strncpy( uid+12, alias->foldername, 64, k_strncpy_always_add_null ); + else + return 0; + + return 1; +} + static void addon_system_init( void ){ u32 reg_size = sizeof(addon_reg)*ADDON_MOUNTED_MAX; addon_system.registry = vg_linear_alloc( vg_mem.rtmemory, reg_size ); @@ -678,6 +715,23 @@ static u16 addon_cache_create_viewer( enum addon_type type, u16 reg_id ){ return cache_id; } +static u16 addon_cache_create_viewer_from_uid( enum addon_type type, + char uid[ADDON_UID_MAX] ){ + addon_alias q; + addon_uid_to_alias( uid, &q ); + if( q.type != type ) return 0; + + u32 reg_id = addon_match( &q ); + + if( reg_id == 0xffffffff ){ + vg_warn( "We dont have the addon '%s' installed.\n", uid ); + return 0; + } + else { + return addon_cache_create_viewer( type, reg_id ); + } +} + static void addon_cache_watch( enum addon_type type, u16 cache_id ){ if( !cache_id ) return; diff --git a/addon.h b/addon.h index 6daf8c8..2b9d9ac 100644 --- a/addon.h +++ b/addon.h @@ -1,6 +1,14 @@ #ifndef ADDON_H #define ADDON_H +#define ADDON_FOLDERNAME_MAX 64 + +/* total count that we have knowledge of */ +#define ADDON_MOUNTED_MAX 128 +#define ADDON_UID_MAX 76 + +#ifndef ADDON_DEFINE_ONLY + #include "skaterift.h" #include "vg/vg_steam_ugc.h" #include "addon_types.h" @@ -9,11 +17,6 @@ #include "world.h" #include "player.h" -#define ADDON_FOLDERNAME_MAX 64 - -/* total count that we have knowledge of */ -#define ADDON_MOUNTED_MAX 128 - typedef struct addon_reg addon_reg; typedef struct addon_cache_entry addon_cache_entry; typedef struct addon_alias addon_alias; @@ -79,7 +82,7 @@ static int addon_get_content_folder( addon_reg *reg, vg_str *folder ); /* scanning routines */ static u32 addon_match( addon_alias *alias ); -static void addon_alias_uid( addon_alias *alias, char buf[76] ); +static void addon_alias_uid( addon_alias *alias, char buf[ADDON_UID_MAX] ); static void addon_mount_content_folder( enum addon_type type, const char *base_folder, const char *content_ext ); @@ -98,5 +101,8 @@ static u16 addon_cache_create_viewer( enum addon_type type, u16 reg_id); static void addon_cache_watch( enum addon_type type, u16 cache_id ); static void addon_cache_unwatch( enum addon_type type, u16 cache_id ); +static u16 addon_cache_create_viewer_from_uid( enum addon_type type, + char uid[ADDON_UID_MAX] ); +#endif #endif /* ADDON_H */ diff --git a/gameserver.c b/gameserver.c index ff8d635..5ed5612 100644 --- a/gameserver.c +++ b/gameserver.c @@ -17,6 +17,7 @@ static void inthandler( int signum ) { #include "highscores.c" #include "servermonitor_server.c" #include "vg/vg_opt.h" +#include "network_common.h" static const u64 k_connection_unauthorized = 0xffffffffffffffff; @@ -49,35 +50,42 @@ static void gameserver_send_to_all( int ignore, } } -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 ); + netmsg_playerjoin join = { .inetmsg_id = k_inetmsg_playerjoin, + .index = index }; gameserver_send_to_all( index, &join, sizeof(join), k_nSteamNetworkingSend_Reliable ); /* update the joining user about current connections */ + + netmsg_playerusername *username = alloca( sizeof(netmsg_playerusername) + + NETWORK_USERNAME_MAX ); + username->inetmsg_id = k_inetmsg_playerusername; + for( int i=0; iactive ) continue; - netmsg_playerjoin init; - gameserver_populate_join_msg( i, &init ); - + /* join */ + netmsg_playerjoin init = { .inetmsg_id = k_inetmsg_playerjoin, + .index = i }; SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( hSteamNetworkingSockets, joiner->connection, &init, sizeof(init), k_nSteamNetworkingSend_Reliable, NULL ); + + /* username */ + username->index = i; + u32 chs = vg_strncpy( client->username, username->name, + NETWORK_USERNAME_MAX, + k_strncpy_always_add_null ); + u32 size = sizeof(netmsg_playerusername) + chs + 1; + SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( + hSteamNetworkingSockets, joiner->connection, + username, size, k_nSteamNetworkingSend_Reliable, NULL ); } } @@ -300,27 +308,31 @@ static void gameserver_rx_200_300( SteamNetworkingMessage_t *msg ){ if( client_id == -1 ) return; if( tmp->inetmsg_id == k_inetmsg_playerusername ){ - if( !packet_minsize( msg, sizeof(netmsg_playerusername) )) + if( !packet_minsize( msg, sizeof(netmsg_playerusername)+1 )) return; struct gameserver_client *client = &gameserver.clients[ client_id ]; netmsg_playerusername *src = msg->m_pData; - vg_info( "%d change name '%s' -> '%s'\n", - client_id, client->username, src->username ); - - vg_strncpy( src->username, client->username, sizeof(client->username), - k_strncpy_always_add_null ); + u32 name_len = network_msgstring( src->name, msg->m_cbSize, + sizeof(netmsg_playerusername), + client->username, + NETWORK_USERNAME_MAX ); /* 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), + netmsg_playerusername *prop = alloca(sizeof(netmsg_playerusername)+ + NETWORK_USERNAME_MAX ); + + prop->inetmsg_id = k_inetmsg_playerusername; + prop->index = client_id; + u32 chs = vg_strncpy( client->username, prop->name, name_len, + k_strncpy_always_add_null ); + + vg_info( "client #%d changed name to: %s\n", client_id, + client->username ); + + u32 propsize = sizeof(netmsg_playerusername) + chs + 1; + gameserver_send_to_all( client_id, prop, propsize, k_nSteamNetworkingSend_Reliable ); } else if( tmp->inetmsg_id == k_inetmsg_playerframe ){ diff --git a/gameserver.h b/gameserver.h index 092f0b5..a3aa574 100644 --- a/gameserver.h +++ b/gameserver.h @@ -8,6 +8,7 @@ #include "vg/vg_steam_http.h" #include "vg/vg_steam_auth.h" #include "network_msg.h" +#include "network_common.h" #include "highscores.h" #include @@ -19,7 +20,7 @@ struct { int active; int authenticated; HSteamNetConnection connection; - char username[32]; + char username[ NETWORK_USERNAME_MAX ]; } clients[ 32 ]; diff --git a/network.c b/network.c index 3235c69..53ebd4b 100644 --- a/network.c +++ b/network.c @@ -1,6 +1,7 @@ #include "player.h" #include "network.h" #include "network_msg.h" +#include "network_common.h" #include "player_remote.h" static void scores_update(void); @@ -131,18 +132,18 @@ static void server_routine_update(void){ #endif static void network_send_username(void){ - netmsg_playerusername update; - memset( &update, 0, sizeof(update) ); - update.inetmsg_id = k_inetmsg_playerusername; - update.index = 0xffffffff; + netmsg_playerusername *update = alloca( sizeof(netmsg_playerusername)+ + NETWORK_USERNAME_MAX ); + 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) ); + u32 chs = str_utf8_collapse( username, update->name, NETWORK_USERNAME_MAX ); SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( hSteamNetworkingSockets, network_client.remote, - &update, sizeof(update), + update, sizeof(netmsg_playerusername)+chs+1, k_nSteamNetworkingSend_Reliable, NULL ); } diff --git a/network_common.h b/network_common.h new file mode 100644 index 0000000..404c000 --- /dev/null +++ b/network_common.h @@ -0,0 +1,21 @@ +#ifndef NETWORK_COMMON_H +#define NETWORK_COMMON_H + +#include "vg/vg_stdint.h" +#include "vg/vg_platform.h" + +#define NETWORK_USERNAME_MAX 32 + +#define ADDON_DEFINE_ONLY + #include "addon.h" +#undef ADDON_DEFINE_ONLY + +static u32 network_msgstring( const char *src, + u32 m_cbSize, u32 base_size, + char *buf, u32 buf_size ){ + + u32 string_len = VG_MIN( m_cbSize - base_size, buf_size ); + return vg_strncpy( src, buf, string_len, k_strncpy_always_add_null ); +} + +#endif /* NETWORK_COMMON_H */ diff --git a/network_msg.h b/network_msg.h index 286bfb0..440facd 100644 --- a/network_msg.h +++ b/network_msg.h @@ -87,7 +87,6 @@ static scoreboard_client_data = { /* player updates 200 */ -/* client -> remote */ typedef struct netmsg_playerframe netmsg_playerframe; enum{ k_inetmsg_playerframe = 200 }; struct netmsg_playerframe{ @@ -97,20 +96,13 @@ struct netmsg_playerframe{ u8 animdata[]; }; -/* remote -> client */ 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 */ }; - -/* remote -> client */ typedef struct netmsg_playerleave netmsg_playerleave; enum{ k_inetmsg_playerleave = 202 }; struct netmsg_playerleave{ @@ -118,13 +110,21 @@ 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]; + char name[]; +}; + +typedef struct netmsg_playeritem netmsg_playeritem; +enum{ k_inetmsg_playeritem = 204 }; +struct netmsg_playeritem{ + u32 inetmsg_id; + u32 index; + u8 type; + char uid[]; }; #pragma pack(pop) diff --git a/player_remote.c b/player_remote.c index dc133b2..b51c857 100644 --- a/player_remote.c +++ b/player_remote.c @@ -1,6 +1,7 @@ #include "player_remote.h" #include "skeleton.h" #include "player_render.h" +#include "network_common.h" static void player_remote_unwatch( struct network_player *player ){ addon_cache_unwatch( k_addon_type_player, player->playermodel_view_slot ); @@ -14,14 +15,6 @@ static void player_remote_clear( struct network_player *player ){ player->subsystem = k_player_subsystem_invalid; } -static void player_remote_clear_interp( u32 index ){ - struct interp_buffer *buf = &netplayers.interp_data[ index ]; - buf->t = -99999999.9; - for( u32 i=0; iframes); i ++ ){ - buf->frames[i].active = 0; - } -} - static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ){ netmsg_blank *tmp = msg->m_pData; @@ -37,13 +30,21 @@ static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ){ /* TODO: interpret the uids */ player->board_view_slot = 0; player->playermodel_view_slot = 0; - player_remote_clear_interp( playerjoin->index ); - - vg_strncpy( playerjoin->username, player->username, - sizeof(player->username), k_strncpy_always_add_null ); +#if 0 + addon_cache_create_viewer_from_uid( k_addon_type_board, + playerjoin->board_uid ); + player->playermodel_view_slot = + addon_cache_create_viewer_from_uid( k_addon_type_player, + playerjoin->playermodel_uid ); +#endif + + struct interp_buffer *buf = &netplayers.interp_data[playerjoin->index]; + buf->t = -99999999.9; + for( u32 i=0; iframes); i ++ ){ + buf->frames[i].active = 0; + } - vg_info( "#%u joined with name: %s\n", - playerjoin->index, player->username ); + vg_info( "#%u joined\n", playerjoin->index ); } else { vg_error( "inetmsg_playerjoin: player index out of range\n" ); @@ -69,10 +70,11 @@ static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ){ 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 ); + network_msgstring( update->name, msg->m_cbSize, sizeof(*update), + player->username, sizeof(player->username) ); + + vg_info( "#%u changed username to: %s\n", player->username ); } else { vg_error( "inetmsg_playerleave: player index out of range\n" ); @@ -126,6 +128,9 @@ static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ){ } } +/* + * Write localplayer pose to network + */ static void remote_player_send_playerframe(void){ u8 sysid = localplayer.subsystem; if( sysid >= k_player_subsystem_max ) return; @@ -150,6 +155,9 @@ static void remote_player_send_playerframe(void){ } } +/* + * Updates network traffic stats + */ static void remote_player_debug_update(void){ if( (vg.time_real - netplayers.last_data_measurement) > 1.0 ){ netplayers.last_data_measurement = vg.time_real; @@ -170,6 +178,9 @@ static void remote_player_debug_update(void){ } } +/* + * Debugging information + */ static void remote_player_network_imgui( m4x4f pv ){ if( !network_client.network_info ) return; @@ -253,6 +264,9 @@ static void remote_player_network_imgui( m4x4f pv ){ } } +/* + * write the remote players final_mtx + */ static void pose_remote_player( u32 index, struct interp_frame *f0, struct interp_frame *f1 ){ @@ -276,20 +290,7 @@ static void pose_remote_player( u32 index, sys1 = player_subsystems[f1->subsystem]; sys1->pose( &f1->data, &pose1 ); - if( pose0.type != pose1.type ){ - /* it would be nice to apply IK pass in-keyframes. TOO BAD! */ - skeleton_copy_pose( sk, pose0.keyframes, posed.keyframes ); - } - else { - skeleton_lerp_pose( sk, pose0.keyframes, pose1.keyframes, t, - posed.keyframes ); - } - - v3_lerp( pose0.root_co, pose1.root_co, t, posed.root_co ); - q_nlerp( pose0.root_q, pose1.root_q, t, posed.root_q ); - posed.type = pose0.type; - posed.board.lean = vg_lerpf( pose0.board.lean, pose1.board.lean, t ); - + lerp_player_pose( &pose0, &pose1, t, &posed ); apply_full_skeleton_pose( &av->sk, &posed, final_mtx ); } else { @@ -297,8 +298,14 @@ static void pose_remote_player( u32 index, } } +/* + * animate remote player and store in final_mtx + */ static void animate_remote_player( u32 index ){ + /* + * Trys to keep the cursor inside the buffer + */ f64 min_time = -999999999.9, max_time = 999999999.9, abs_max_time = -999999999.9; @@ -342,3 +349,31 @@ static void animate_remote_player( u32 index ){ return; } } + +/* + * Update full final_mtx for all remote players + */ +static void animate_remote_players(void){ + for( u32 i=0; iactive ) continue; + + animate_remote_player( i ); + } +} + +/* + * Draw remote players + */ +static void render_remote_players( world_instance *world, camera *cam ){ + for( u32 i=0; iactive ) continue; + + struct player_avatar *av = localplayer.playeravatar; + + struct player_model *model = &localplayer.fallback_model; + render_playermodel( cam, world, 0, model, &av->sk, + &netplayers.final_mtx[ av->sk.bone_count*i ] ); + } +} diff --git a/player_render.c b/player_render.c index 22938b5..3f72657 100644 --- a/player_render.c +++ b/player_render.c @@ -202,6 +202,25 @@ static void player_copy_frame_animator( replay_frame *frame ){ } } +static void lerp_player_pose( player_pose *pose0, player_pose *pose1, f32 t, + player_pose *posed ){ + struct skeleton *sk = &localplayer.playeravatar->sk; + + v3_lerp( pose0->root_co, pose1->root_co, t, posed->root_co ); + q_nlerp( pose0->root_q, pose1->root_q, t, posed->root_q ); + posed->type = pose0->type; + posed->board.lean = vg_lerpf( pose0->board.lean, pose1->board.lean, t ); + + if( pose0->type != pose1->type ){ + /* it would be nice to apply IK pass in-keyframes. TOO BAD! */ + skeleton_copy_pose( sk, pose0->keyframes, posed->keyframes ); + } + else { + skeleton_lerp_pose( sk, pose0->keyframes, pose1->keyframes, t, + posed->keyframes ); + } +} + static void player__animate_from_replay( replay_buffer *replay ){ replay_frame *frame = replay->cursor_frame, *next = NULL; @@ -223,22 +242,7 @@ static void player__animate_from_replay( replay_buffer *replay ){ sys0->pose( a0, &pose0 ); sys1->pose( a1, &pose1 ); - v3_lerp( pose0.root_co, pose1.root_co, t, localplayer.pose.root_co ); - q_nlerp( pose0.root_q, pose1.root_q, t, localplayer.pose.root_q ); - localplayer.pose.type = pose0.type; - localplayer.pose.board.lean = vg_lerpf( pose0.board.lean, - pose1.board.lean, t ); - - struct skeleton *sk = &localplayer.playeravatar->sk; - if( pose0.type != pose1.type ){ - /* it would be nice to apply IK pass in-keyframes. TOO BAD! */ - skeleton_copy_pose( sk, pose0.keyframes, - localplayer.pose.keyframes ); - } - else { - skeleton_lerp_pose( sk, pose0.keyframes, pose1.keyframes, - t, localplayer.pose.keyframes ); - } + lerp_player_pose( &pose0, &pose1, t, &localplayer.pose ); } else{ struct player_subsystem_interface diff --git a/player_render.h b/player_render.h index f25f68b..bbb9630 100644 --- a/player_render.h +++ b/player_render.h @@ -89,5 +89,7 @@ static void render_playermodel( camera *cam, world_instance *world, m4x3f *final_mtx ); static void apply_full_skeleton_pose( struct skeleton *sk, player_pose *pose, m4x3f *final_mtx ); +static void lerp_player_pose( player_pose *pose0, player_pose *pose1, f32 t, + player_pose *posed ); #endif /* PLAYER_RENDER_H */ diff --git a/skaterift.c b/skaterift.c index 81b8091..fc537ce 100644 --- a/skaterift.c +++ b/skaterift.c @@ -455,41 +455,6 @@ static void render_player_transparent(void){ player__render( &small_cam ); } -static void animate_remote_players(void){ - for( u32 i=0; iactive ) continue; - - animate_remote_player( i ); -#if 0 - if( player->subsystem > k_player_subsystem_max ) continue; - - struct player_subsystem_interface *sys = - player_subsystems[player->subsystem]; - - struct player_avatar *av = localplayer.playeravatar; - - player_pose pose; - sys->pose( &player->animdata, &pose ); - apply_full_skeleton_pose( &av->sk, &pose, - &netplayers.final_mtx[ av->sk.bone_count*i ] ); -#endif - } -} - -static void render_remote_players( world_instance *world, camera *cam ){ - for( u32 i=0; iactive ) continue; - - struct player_avatar *av = localplayer.playeravatar; - - struct player_model *model = &localplayer.fallback_model; - render_playermodel( cam, world, 0, model, &av->sk, - &netplayers.final_mtx[ av->sk.bone_count*i ] ); - } -} - static void render_scene(void){ /* Draw world */ glEnable( GL_DEPTH_TEST ); diff --git a/steam.h b/steam.h index 730784e..2c8bd2d 100644 --- a/steam.h +++ b/steam.h @@ -171,13 +171,12 @@ static u32 utf8_byte0_byte_count( u8 char0 ) return 0; } -static void str_utf8_collapse( const char *str, char *buf, u32 length ) -{ +static u32 str_utf8_collapse( const char *str, char *buf, u32 length ){ u8 *ustr = (u8 *)str; u32 utf32_code = 0x00000000; u32 i=0, j=0, utf32_byte_ct=0; - for(;i < length-1;){ + for(;j < length-1;){ if( ustr[i] == 0x00 ) break; @@ -210,6 +209,7 @@ static void str_utf8_collapse( const char *str, char *buf, u32 length ) } buf[j] = 0x00; + return j; } static int steam_init(void){ -- 2.25.1