X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;ds=sidebyside;f=network.h;h=1644982917a49d4b5d08e7bf1abb72bfaf396f40;hb=0945c6c301e38138b6ac54a02d5b3aea602de526;hp=f97cfbc8f5fdfeb3d50b4009b03c51fb07306e07;hpb=91d035f4845a6f9f62487b43e5142c4148e7f047;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/network.h b/network.h index f97cfbc..1644982 100644 --- a/network.h +++ b/network.h @@ -2,7 +2,241 @@ #define NETWORK_H #include "vg/vg_stdint.h" +#include "steam.h" +#include "network_msg.h" +/* + * Interface + */ +/* Call it at start; Connects us to the gameserver */ +static void network_init(void); +/* Run this from main loop */ +static void network_update(void); + +/* Call it at shutdown */ +static void network_end(void); + +/* + * Can buffer up a bunch of these by calling many times, they will be + * sent at the next connection + */ +static void network_submit_highscore( u32 trackid, u16 points, u16 time ); + + +/* + * Game endpoints are provided with the same names to allow running without a + * network connection. + */ +#ifdef SR_NETWORKED + +/* + * Runtime connection stuff + */ +static u8 steam_app_ticket[ 1024 ]; +static u32 steam_app_ticket_length; + +static HSteamNetConnection cremote; +static ESteamNetworkingConnectionState cremote_state = + k_ESteamNetworkingConnectionState_None; + +/* + * Implementation + */ + +static void scores_update(void); + +static void on_auth_ticket_recieved( void *result, void *context ) +{ + EncryptedAppTicketResponse_t *response = result; + + if( response->m_eResult == k_EResultOK ) + { + vg_info( " New app ticket ready\n" ); + } + else + { + vg_warn( " Could not request new encrypted app ticket (%u)\n", + response->m_eResult ); + } + + if( SteamAPI_ISteamUser_GetEncryptedAppTicket( hSteamUser, + steam_app_ticket, + vg_list_size(steam_app_ticket), + &steam_app_ticket_length )) + { + vg_success( " Loaded app ticket (%u bytes)\n", steam_app_ticket_length ); + } + else + { + vg_error( " No ticket availible\n" ); + steam_app_ticket_length = 0; + } +} + +static void request_auth_ticket(void) +{ + /* + * TODO Check for one thats cached on the disk and load it. + * This might be OK though because steam seems to cache the result + */ + + vg_info( "Requesting new authorization ticket\n" ); + steam_async *call = steam_new_async(); + call->data = NULL; + call->p_handler = on_auth_ticket_recieved; + call->id = SteamAPI_ISteamUser_RequestEncryptedAppTicket( hSteamUser, + NULL, 0 ); +} + +static void server_connect(void) +{ + /* Connect to server if not connected */ + + SteamNetworkingIPAddr remoteAddr; + +#define USE_LOCALHOST +#ifdef USE_LOCALHOST + SteamAPI_SteamNetworkingIPAddr_SetIPv6LocalHost( &remoteAddr, 27402 ); +#else + const char *server_lon1 = "46.101.34.155:27402"; + SteamAPI_SteamNetworkingIPAddr_ParseString( &remoteAddr, server_lon1 ); +#endif + + char buf[256]; + SteamAPI_SteamNetworkingIPAddr_ToString( &remoteAddr, buf, 256, 1 ); + vg_info( "connect to: %s\n", buf ); + + cremote = SteamAPI_ISteamNetworkingSockets_ConnectByIPAddress( + hSteamNetworkingSockets, &remoteAddr, 0, NULL ); +} + +static void scores_update(void) +{ + vg_log( "scores_update()\n" ); + + if( cremote_state == k_ESteamNetworkingConnectionState_Connected ) + { + /* + * request updated scores + */ + netmsg_scores_request req; + req.inetmsg_id = k_inetmsg_scores_request; + + SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( + hSteamNetworkingSockets, cremote, &req, + sizeof(netmsg_scores_request), + k_nSteamNetworkingSend_Reliable, NULL ); + } + else + { + /* + * if we are not connected, make a connection to the server and then in + * the future this function will be called again when it is connected + */ + server_connect(); + } +} + +static void poll_connection(void) +{ + SteamNetworkingMessage_t *messages[32]; + int len; + + while(1) + { + len = SteamAPI_ISteamNetworkingSockets_ReceiveMessagesOnConnection( + hSteamNetworkingSockets, cremote, messages, vg_list_size(messages)); + + if( len <= 0 ) + return; + + for( int i=0; im_cbSize < sizeof(netmsg_blank) ) + { + vg_warn( "Discarding message (too small: %d)\n", + msg->m_cbSize ); + continue; + } + + netmsg_blank *tmp = msg->m_pData; + if( tmp->inetmsg_id == k_inetmsg_scores_info ) + { + netmsg_scores_info *info = msg->m_pData; + vg_log( "Recieved %u score records\n", info->record_count ); + + SteamAPI_ISteamNetworkingSockets_CloseConnection( + hSteamNetworkingSockets, cremote, 0, NULL, 1 ); + cremote_state = k_ESteamNetworkingConnectionState_None; + } + + SteamAPI_SteamNetworkingMessage_t_Release( msg ); + } + } +} + +static u64 in_server_ticks( double seconds ) +{ + return (u64)(seconds / 0.1); +} + +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 ); + vg_info( " %s -> %s\n", + string_ESteamNetworkingConnectionState(info->m_info.m_eState), + string_ESteamNetworkingConnectionState(info->m_eOldState) ); + + if( info->m_hConn == cremote ) + { + cremote_state = info->m_info.m_eState; + if( info->m_info.m_eState == + k_ESteamNetworkingConnectionState_Connected ) + { + vg_success(" Connected to remote server\n"); + scores_update(); + } + } + else + { + vg_warn( " Recieved signal from unknown connection\n" ); + } +} + +static void network_init(void) +{ + if( steam_ready ) + { + steam_register_callback( k_iSteamNetConnectionStatusChangedCallBack, + on_server_connect_status ); + request_auth_ticket(); + } +} + +static void network_update(void) +{ + if( steam_ready ) + { + static double last_update = -9000.0; + poll_connection(); + + if( vg_time > (last_update + 60.0) ) + { + last_update = vg_time; + scores_update(); + } + } +} + +static void network_end(void) +{ + /* TODO: Fire off any buffered highscores that need to be setn */ +} + +#endif #endif /* NETWORK_H */