X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=network.c;h=fdec386ccd62f0e884414ea860f5f28c4df67612;hb=494c85703c76c4123c49937a32584840b6be1470;hp=da0be1e392e07fc65f7df722041a4c913e2af1a9;hpb=6ba5c35d106d749a1ebafbd3cbe18c3a02f781d3;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/network.c b/network.c index da0be1e..fdec386 100644 --- a/network.c +++ b/network.c @@ -1,3 +1,8 @@ +#include "skaterift.h" +#include "vg/vg_steam.h" +#include "vg/vg_steam_networking.h" +#include "vg/vg_steam_auth.h" +#include "vg/vg_steam_friends.h" #include "player.h" #include "network.h" #include "network_msg.h" @@ -6,10 +11,30 @@ #include "world.h" #include "world_sfd.h" #include "world_routes.h" +#include "vg/vg_imgui.h" +#include "gui.h" +#include "ent_region.h" +#include "vg/vg_loader.h" + +#ifdef _WIN32 + #include + #include +#else + #include + #include + #include +#endif + +struct network_client network_client = +{ + .auth_mode = eServerModeAuthentication, + .state = k_ESteamNetworkingConnectionState_None, + .last_intent_change = -99999.9 +}; static void scores_update(void); -static int packet_minsize( SteamNetworkingMessage_t *msg, u32 size ){ +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; @@ -58,6 +83,9 @@ static void request_auth_ticket(void){ } static void network_send_username(void){ + if( !network_connected() ) + return; + netmsg_playerusername *update = alloca( sizeof(netmsg_playerusername)+ NETWORK_USERNAME_MAX ); update->inetmsg_id = k_inetmsg_playerusername; @@ -73,6 +101,26 @@ static void network_send_username(void){ k_nSteamNetworkingSend_Reliable, NULL ); } +void network_send_region(void) +{ + if( !network_connected() ) + return; + + netmsg_region *region = alloca( sizeof(netmsg_region) + NETWORK_REGION_MAX ); + + region->inetmsg_id = k_inetmsg_region; + region->client = 0; + region->flags = global_ent_region.flags; + + u32 l = vg_strncpy( global_ent_region.location, region->loc, + NETWORK_REGION_MAX, k_strncpy_always_add_null ); + + SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( + hSteamNetworkingSockets, network_client.remote, + region, sizeof(netmsg_region)+l+1, + k_nSteamNetworkingSend_Reliable, NULL ); +} + static void network_send_request( netmsg_request *req, vg_msg *body, void (*callback)( netmsg_request *res, vg_msg *body, @@ -134,10 +182,10 @@ static void network_scoreboard_callback( netmsg_request *res, vg_msg *body, * . * 10+ specific week index */ -static void network_request_scoreboard( const char *mod_uid, - const char *route_uid, - u32 week, u64 userdata ){ - if( !network_client.remote ) +void network_request_scoreboard( const char *mod_uid, + const char *route_uid, + u32 week, u64 userdata ){ + if( !network_connected() ) return; netmsg_request *req = alloca( sizeof(netmsg_request) + 512 ); @@ -148,7 +196,7 @@ static void network_request_scoreboard( const char *mod_uid, vg_msg_wkvstr( &data, "endpoint", "scoreboard" ); vg_msg_wkvstr( &data, "mod", mod_uid ); vg_msg_wkvstr( &data, "route", route_uid ); - vg_msg_wkvu32( &data, "week", week ); + vg_msg_wkvnum( &data, "week", k_vg_msg_u32, 1, &week ); network_send_request( req, &data, network_scoreboard_callback, userdata ); } @@ -159,9 +207,9 @@ static void network_publish_callback( netmsg_request *res, vg_msg *body, } } -static void network_publish_laptime( const char *mod_uid, - const char *route_uid, f64 lap_time ){ - if( !network_client.remote ) +void network_publish_laptime( const char *mod_uid, + const char *route_uid, f64 lap_time ){ + if( !network_connected() ) return; i32 time_centiseconds = lap_time * 100.0; @@ -174,7 +222,7 @@ static void network_publish_laptime( const char *mod_uid, vg_msg_wkvstr( &data, "endpoint", "setlap" ); vg_msg_wkvstr( &data, "mod", mod_uid ); vg_msg_wkvstr( &data, "route", route_uid ); - vg_msg_wkvi32( &data, "time", time_centiseconds ); + vg_msg_wkvnum( &data, "time", k_vg_msg_i32, 1, &time_centiseconds ); network_send_request( req, &data, network_publish_callback, 0 ); } @@ -209,8 +257,9 @@ static void network_request_rx_300_400( SteamNetworkingMessage_t *msg ){ } } -static void network_send_item( enum netmsg_playeritem_type type ){ - if( !network_client.remote ) +void network_send_item( enum netmsg_playeritem_type type ) +{ + if( !network_connected() ) return; netmsg_playeritem *item = @@ -241,8 +290,6 @@ static void network_send_item( enum netmsg_playeritem_type type ){ view_id = localplayer.playermodel_view_slot; addon_type = k_addon_type_player; } - else - assert(0); struct addon_cache *cache = &addon_system.cache[addon_type]; vg_pool *pool = &cache->pool; @@ -267,12 +314,89 @@ static void network_disconnect(void){ SteamAPI_ISteamNetworkingSockets_CloseConnection( hSteamNetworkingSockets, network_client.remote, 0, NULL, 0 ); network_client.remote = 0; + network_client.state = k_ESteamNetworkingConnectionState_None; for( int i=0; iattachments[0].id; +} + static void on_server_connect_status( CallbackMsg_t *msg ){ SteamNetConnectionStatusChangedCallback_t *info = (void *)msg->m_pubParam; vg_info( " Connection status changed for %lu\n", info->m_hConn ); @@ -287,6 +411,14 @@ static void on_server_connect_status( CallbackMsg_t *msg ){ k_ESteamNetworkingConnectionState_Connected ){ vg_success(" Connected to remote server.. authenticating\n"); + /* send version info to server */ + netmsg_version version; + version.inetmsg_id = k_inetmsg_version; + version.version = NETWORK_SKATERIFT_VERSION; + SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( + hSteamNetworkingSockets, network_client.remote, &version, + sizeof(netmsg_version), k_nSteamNetworkingSend_Reliable, NULL ); + /* 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; @@ -299,18 +431,12 @@ static void on_server_connect_status( CallbackMsg_t *msg ){ SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( hSteamNetworkingSockets, network_client.remote, auth, size, k_nSteamNetworkingSend_Reliable, NULL ); - - network_send_username(); - - for( u32 i=0; im_info.m_eState == k_ESteamNetworkingConnectionState_ClosedByPeer ){ if( info->m_info.m_eEndReason == - k_ESteamNetConnectionEnd_Remote_Max ){ + k_ESteamNetConnectionEnd_Misc_InternalError ){ network_client.retries = 40; } network_disconnect(); @@ -323,37 +449,78 @@ static void on_server_connect_status( CallbackMsg_t *msg ){ else{ //vg_warn( " Recieved signal from unknown connection\n" ); } + + render_server_status_gui(); } static void on_persona_state_change( CallbackMsg_t *msg ){ - if( network_client.remote ){ - PersonaStateChange_t *info = (void *)msg->m_pubParam; + if( !network_connected() ) + return; - ISteamUser *hSteamUser = SteamAPI_SteamUser(); - - vg_info( "User: %llu, change: %u\n", info->m_ulSteamID, - info->m_nChangeFlags ); + PersonaStateChange_t *info = (void *)msg->m_pubParam; + ISteamUser *hSteamUser = SteamAPI_SteamUser(); - if( info->m_ulSteamID == SteamAPI_ISteamUser_GetSteamID(hSteamUser) ){ - if( info->m_nChangeFlags & k_EPersonaChangeName ){ - network_send_username(); + vg_info( "User: %llu, change: %u\n", info->m_ulSteamID, + info->m_nChangeFlags ); + + if( info->m_ulSteamID == SteamAPI_ISteamUser_GetSteamID(hSteamUser) ){ + if( info->m_nChangeFlags & k_EPersonaChangeName ){ + network_send_username(); + } + } + + if( info->m_nChangeFlags & k_EPersonaChangeRelationshipChanged ){ + for( u32 i=0; isteamid == info->m_ulSteamID ){ + player_remote_update_friendflags( rp ); } } } } -static void network_connect(void){ - /* Connect to server if not connected */ - SteamNetworkingIPAddr remoteAddr; - SteamAPI_SteamNetworkingIPAddr_ParseString( &remoteAddr, - network_client.server_adress ); +void network_set_host( const char *host_str, const char *port_str ) +{ + vg_strncpy( host_str, network_client.host_adress, + sizeof(network_client.host_adress), k_strncpy_overflow_fatal ); - char buf[256]; - SteamAPI_SteamNetworkingIPAddr_ToString( &remoteAddr, buf, 256, 1 ); - vg_info( "connect to: %s\n", buf ); + memset( &network_client.ip, 0, sizeof(network_client.ip) ); + network_client.ip_resolved = 0; + + if( port_str ) + { + vg_strncpy( port_str, network_client.host_port, + sizeof(network_client.host_port), k_strncpy_overflow_fatal ); + } + else + { + vg_str str; + vg_strnull( &str, network_client.host_port, + sizeof(network_client.host_port) ); + vg_strcati32( &str, NETWORK_PORT ); + } + + network_client.ip.m_port = atoi( network_client.host_port ); +} +static void network_connect(void) +{ + VG_ASSERT( network_client.ip_resolved ); + + vg_info( "connecting...\n" ); network_client.remote = SteamAPI_ISteamNetworkingSockets_ConnectByIPAddress( - hSteamNetworkingSockets, &remoteAddr, 0, NULL ); + hSteamNetworkingSockets, &network_client.ip, 0, NULL ); +} + +static void network_sign_on_complete(void){ + vg_success( "Sign on completed\n" ); + + /* send our init info */ + network_send_username(); + for( u32 i=0; iinetmsg_id >= 300) && (tmp->inetmsg_id < 400) ){ network_request_rx_300_400( msg ); } + else { + if( tmp->inetmsg_id == k_inetmsg_version ){ + netmsg_version *version = msg->m_pData; + if( version->version != NETWORK_SKATERIFT_VERSION ){ + network_disconnect(); + /* we dont want to connect to this server ever */ + network_client.retries = 999; + network_client.last_attempt = 999999999.9; + vg_error( "version mismatch with server\n" ); + } + else { + network_client.remote_version = version->version; + network_sign_on_complete(); + } + } + } SteamAPI_SteamNetworkingMessage_t_Release( msg ); } } } -static void network_update(void){ +static void network_resolve_host_async( void *payload, u32 size ) +{ + u32 *status = payload; + network_client.ip_resolved = *status; + + char buf[256]; + SteamAPI_SteamNetworkingIPAddr_ToString( &network_client.ip, buf, 256, 1 ); + vg_info( "Resolved host address to: %s\n", buf ); +} + +static void network_resolve_host_thread( void *_ ) +{ + vg_async_item *call = vg_async_alloc(8); + u32 *status = call->payload; + *status = 0; + + if( (network_client.host_adress[0] >= '0') && + (network_client.host_adress[0] <= '9') ) + { + SteamAPI_SteamNetworkingIPAddr_ParseString( + &network_client.ip, + network_client.host_adress ); + network_client.ip.m_port = atoi( network_client.host_port ); + *status = 1; + goto end; + } + + vg_info( "Resolving host.. %s (:%s)\n", + network_client.host_adress, network_client.host_port ); + + struct addrinfo hints; + struct addrinfo *result; + + /* Obtain address(es) matching host/port. */ + + memset( &hints, 0, sizeof(hints) ); + hints.ai_family = AF_INET6; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG; + hints.ai_protocol = 0; + + int s = getaddrinfo( network_client.host_adress, network_client.host_port, + &hints, &result); + if( s != 0 ) + { +#ifndef _WIN32 + vg_error( "getaddrinfo: %s\n", gai_strerror(s) ); +#endif + + if( !strcmp( network_client.host_adress, "skaterift.com" ) ) + { + vg_warn( "getaddrinfo failed for skaterift.com;\n " + "falling back to a hardcoded IPv4\n" ); + strcpy( network_client.host_adress, "46.101.34.155" ); + SteamAPI_SteamNetworkingIPAddr_ParseString( + &network_client.ip, + network_client.host_adress ); + network_client.ip.m_port = NETWORK_PORT; + *status = 1; + } + + goto end; + } + + struct sockaddr_in6 *inaddr = (struct sockaddr_in6 *)result->ai_addr; + memcpy( network_client.ip.m_ipv6, &inaddr->sin6_addr, 16 ); + freeaddrinfo( result ); + + *status = 1; + +end: vg_async_dispatch( call, network_resolve_host_async ); +} + +void network_update(void) +{ if( !steam_ready ) return; ESteamNetworkingConnectionState state = network_client.state; - if( state == k_ESteamNetworkingConnectionState_Connected ){ + if( network_client.user_intent == k_server_intent_offline ) + { + if( state != k_ESteamNetworkingConnectionState_None ) + network_disconnect(); + + return; + } + + if( state == k_ESteamNetworkingConnectionState_Connected ) + { poll_remote_connection(); f64 frame_delta = vg.time_real - network_client.last_frame; - if( frame_delta > NETWORK_FRAMERATE ){ + if( frame_delta > NETWORK_FRAMERATE ) + { network_client.last_frame = vg.time_real; remote_player_send_playerframe(); - player__clear_sfx_buffer(); + localplayer.sfx_buffer_count = 0; } remote_player_debug_update(); } - else { + else + { if( (state == k_ESteamNetworkingConnectionState_Connecting) || - (state == k_ESteamNetworkingConnectionState_FindingRoute) ){ + (state == k_ESteamNetworkingConnectionState_FindingRoute) ) + { return; } - else { + else + { f64 waited = vg.time_real - network_client.last_attempt, min_wait = 1.0; @@ -422,17 +692,65 @@ static void network_update(void){ if( waited < min_wait ) return; + + if( !network_client.ip_resolved ) + { + if( vg_loader_availible() ) + { + vg_loader_start( network_resolve_host_thread, NULL ); + } + else return; + } + else + network_connect(); - network_connect(); network_client.retries ++; network_client.last_attempt = vg.time_real; } } } -static void network_init(void){ +void chat_send_message( const char *message ) +{ + if( !network_connected() ){ + return; + } + + netmsg_chat *chat = alloca( sizeof(netmsg_chat) + NETWORK_MAX_CHAT ); + chat->inetmsg_id = k_inetmsg_chat; + chat->client = 0; + + u32 l = vg_strncpy( message, chat->msg, NETWORK_MAX_CHAT, + k_strncpy_always_add_null ); + + SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( + hSteamNetworkingSockets, network_client.remote, + chat, sizeof(netmsg_chat)+l+1, + k_nSteamNetworkingSend_Reliable, NULL ); +} + +static int cmd_network_send_message( int argc, const char *argv[] ){ + char buf[ NETWORK_MAX_CHAT ]; + vg_str str; + vg_strnull( &str, buf, NETWORK_MAX_CHAT ); + + for( int i=0; i