X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=steam.c;fp=steam.c;h=a9484ddc71ef8d1f80f3405a1bbfc0d31cfaaf98;hb=5f6a4f9df6c8accc89f1920bfe9ace3cbac4c4b6;hp=0000000000000000000000000000000000000000;hpb=a109f126d8adab622e38fbcc2d4281e75255246a;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/steam.c b/steam.c new file mode 100644 index 0000000..a9484dd --- /dev/null +++ b/steam.c @@ -0,0 +1,303 @@ +#include "vg/vg_steam.h" +#include "vg/vg_steam_utils.h" +#include "vg/vg_steam_networking.h" +#include "vg/vg_steam_auth.h" +#include "vg/vg_steam_http.h" +#include "vg/vg_steam_friends.h" +#include "vg/vg_steam_user_stats.h" +#include "submodules/anyascii/impl/c/anyascii.c" +#include "skaterift.h" +#include + +/* + * We only want to use steamworks if building for the networked version, + * theres not much point otherwise. We mainly want steamworks for setting + * achievements etc.. so that includes our own server too. + * + * This file also wraps the functions and interfaces that we want to use to + * make them a bit easier to read, since they are the flat API they have very + * long names. in non-networked builds they will return default errors or do + * nothing. + */ + +char steam_username_at_startup[128] = "Unassigned"; + +static void recv_steam_warning( int severity, const char *msg ) +{ + if( severity == 0 ) + vg_low( "%s\n", msg ); + else + vg_info( "%s\n", msg ); +} + +int steam_ready = 0, + steam_stats_ready = 0; + +void *hSteamNetworkingSockets, *hSteamUser, *hSteamUserStats; +static HSteamPipe hSteamClientPipe; + +static const char *steam_achievement_names[] = +{ + "ALBERT", "MARC", "JANET", "BERNADETTA", + "ROUTE_MPY", "ROUTE_MPG", "ROUTE_MPB", "ROUTE_MPR", + "ROUTE_TO", "ROUTE_TC", "CITY_COMPLETE", "MTZERO_SILVER", "MTZERO_GOLD", + "80FT" +}; + +void steam_store_achievements(void) +{ + if( steam_ready && steam_stats_ready ){ + SteamAPI_ISteamUserStats_StoreStats( hSteamUserStats ); + } +} + +void update_ach_models(void); +void steam_set_achievement( const char *name ) +{ + if( skaterift.demo_mode ) + return; + + /* hack lol */ + if( !strcmp(name,"MARC") ) skaterift.achievements |= 0x1; + if( !strcmp(name,"ALBERT") ) skaterift.achievements |= 0x2; + if( !strcmp(name,"JANET") ) skaterift.achievements |= 0x4; + if( !strcmp(name,"BERNADETTA") ) skaterift.achievements |= 0x8; + update_ach_models(); + + if( steam_ready && steam_stats_ready ){ + if( SteamAPI_ISteamUserStats_SetAchievement( hSteamUserStats, name ) ){ + vg_success( "Achievement set! '%s'\n", name ); + + } + else{ + vg_warn( "Failed to set achievement: %s\n", name ); + } + } + else{ + vg_warn( "Failed to set achievement (steam not ready): %s\n", name ); + } +} + +void steam_clear_achievement( const char *name ) +{ + if( steam_ready && steam_stats_ready ){ + if( SteamAPI_ISteamUserStats_ClearAchievement( hSteamUserStats, name ) ){ + vg_info( "Achievement cleared: '%s'\n", name ); + } + else{ + vg_warn( "Failed to clear achievement: %s\n", name ); + } + } + else{ + vg_warn( "Failed to clear achievement (steam not ready): %s\n", name ); + } +} + + +void steam_print_all_achievements(void) +{ + vg_info( "Achievements: \n" ); + + if( steam_ready && steam_stats_ready ){ + for( int i=0; im_pubParam; + + if( rec->m_eResult == k_EResultOK ){ + vg_info( "Recieved stats for: %lu (user: %lu)\n", rec->m_nGameID, + rec->m_steamIDUser ); + steam_stats_ready = 1; + + steamapi_bool set = 0; + if( SteamAPI_ISteamUserStats_GetAchievement( + hSteamUserStats, "MARC", &set ) ){ + if( set ) skaterift.achievements |= 0x1; + } + if( SteamAPI_ISteamUserStats_GetAchievement( + hSteamUserStats, "ALBERT", &set ) ){ + if( set ) skaterift.achievements |= 0x2; + } + if( SteamAPI_ISteamUserStats_GetAchievement( + hSteamUserStats, "JANET", &set ) ){ + if( set ) skaterift.achievements |= 0x4; + } + if( SteamAPI_ISteamUserStats_GetAchievement( + hSteamUserStats, "BERNADETTA", &set ) ){ + if( set ) skaterift.achievements |= 0x8; + } + update_ach_models(); + } + else{ + vg_error( "Error recieveing stats for user (%u)\n", rec->m_eResult ); + } +} + +static u32 utf8_byte0_byte_count( u8 char0 ) +{ + for( u32 k=2; k<4; k++ ){ + if( !(char0 & (0x80 >> k)) ) + return k; + } + + return 0; +} + +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(;j < length-1;){ + if( ustr[i] == 0x00 ) + break; + + if( ustr[i] & 0x80 ){ + if( utf32_byte_ct ){ + utf32_byte_ct --; + utf32_code |= (ustr[i] & 0x3F) << (utf32_byte_ct*6); + + if( !utf32_byte_ct ){ + const char *match; + size_t chars = anyascii( utf32_code, &match ); + + for( u32 k=0; k> utf32_byte_ct); + utf32_code <<= utf32_byte_ct*6; + } + } + else{ + utf32_byte_ct = 0x00; + buf[j ++] = str[i]; + } + + i++; + } + + buf[j] = 0x00; + return j; +} + +int steam_init(void) +{ + const char *username = "offline player"; + + vg_info( "Initializing steamworks\n" ); + + if( !SteamAPI_Init() ){ + printf("\n"); + vg_error( "Steamworks failed to initialize\n" ); + return 1; + } + + steam_ready = 1; + + SteamAPI_ManualDispatch_Init(); + + /* Connect interfaces */ + hSteamClientPipe = SteamAPI_GetHSteamPipe(); + hSteamNetworkingSockets = SteamAPI_SteamNetworkingSockets_SteamAPI(); + hSteamUser = SteamAPI_SteamUser(); + + ISteamUtils *utils = SteamAPI_SteamUtils(); + SteamAPI_ISteamUtils_SetWarningMessageHook( utils, recv_steam_warning ); + + printf("\n"); + vg_success( "\nSteamworks API running\n" ); + + ISteamFriends *hSteamFriends = SteamAPI_SteamFriends(); + username = SteamAPI_ISteamFriends_GetPersonaName( hSteamFriends ); + + /* + * Request stats + * -------------------------------------------------------- + */ + hSteamUserStats = SteamAPI_SteamUserStats(); + steam_register_callback( k_iUserStatsReceived, + steam_on_recieve_current_stats ); + + if( !SteamAPI_ISteamUserStats_RequestCurrentStats( hSteamUserStats ) ) + vg_warn( "No Steam Logon: Cannot request stats\n" ); + + + vg_console_reg_cmd( "ach", steam_achievement_ccmd, NULL ); + + /* TODO: On username update callback */ + str_utf8_collapse( username, steam_username_at_startup, + vg_list_size(steam_username_at_startup) ); + + return 1; +} + +void steam_update(void) +{ + if( steam_ready ){ + steamworks_event_loop( hSteamClientPipe ); + } +} + +void steam_end(void) +{ + if( steam_ready ){ + vg_info( "Shutting down\n..." ); + SteamAPI_Shutdown(); + } +}