CSGOClient::CSGOClient() :m_availableCb(this, &CSGOClient::OnMessageAvailable) , m_failedCb(this, &CSGOClient::OnMessageFailed) , m_welcomeHandler(this, &CSGOClient::OnClientWelcome) { m_gameCoordinator = (ISteamGameCoordinator*)SteamClient() ->GetISteamGenericInterface(GetHSteamUser(), GetHSteamPipe(), STEAMGAMECOORDINATOR_INTERFACE_VERSION); RegisterHandler(k_EMsgGCClientWelcome, &m_welcomeHandler); CMsgClientHello hello; hello.set_client_session_need(1); if (SendGCMessage(k_EMsgGCClientHello, &hello) != k_EGCResultOK) throw BoilerException("failed to send GCClientHello"); }
static int RealMain( const char *pchCmdLine, HINSTANCE hInstance, int nCmdShow ) { if ( SteamAPI_RestartAppIfNecessary( k_uAppIdInvalid ) ) { // if Steam is not running or the game wasn't started through Steam, SteamAPI_RestartAppIfNecessary starts the // local Steam client and also launches this game again. // Once you get a public Steam AppID assigned for this game, you need to replace k_uAppIdInvalid with it and // removed steam_appid.txt from the game depot. return EXIT_FAILURE; } // Init Steam CEG if ( !Steamworks_InitCEGLibrary() ) { OutputDebugString( "Steamworks_InitCEGLibrary() failed\n" ); Alert( "Fatal Error", "Steam must be running to play this game (InitDrmLibrary() failed).\n" ); return EXIT_FAILURE; } // Initialize SteamAPI, if this fails we bail out since we depend on Steam for lots of stuff. // You don't necessarily have to though if you write your code to check whether all the Steam // interfaces are NULL before using them and provide alternate paths when they are unavailable. // // This will also load the in-game steam overlay dll into your process. That dll is normally // injected by steam when it launches games, but by calling this you cause it to always load, // even when not launched via steam. if ( !SteamAPI_Init() ) { OutputDebugString( "SteamAPI_Init() failed\n" ); Alert( "Fatal Error", "Steam must be running to play this game (SteamAPI_Init() failed).\n" ); return EXIT_FAILURE; } // set our debug handler SteamClient()->SetWarningMessageHook( &SteamAPIDebugTextHook ); // Tell Steam where it's overlay should show notification dialogs, this can be top right, top left, // bottom right, bottom left. The default position is the bottom left if you don't call this. // Generally you should use the default and not call this as users will be most comfortable with // the default position. The API is provided in case the bottom right creates a serious conflict // with important UI in your game. SteamUtils()->SetOverlayNotificationPosition( k_EPositionTopRight ); // Ensure that the user has logged into Steam. This will always return true if the game is launched // from Steam, but if Steam is at the login prompt when you run your game from the debugger, it // will return false. if ( !SteamUser()->BLoggedOn() ) { OutputDebugString( "Steam user is not logged in\n" ); Alert( "Fatal Error", "Steam user must be logged in to play this game (SteamUser()->BLoggedOn() returned false).\n" ); return EXIT_FAILURE; } // We are going to use the controller interface, initialize it, which is a seperate step as it // create a new thread in the game proc and we don't want to force that on games that don't // have native Steam controller implementations char rgchCWD[1024]; _getcwd( rgchCWD, sizeof( rgchCWD ) ); char rgchFullPath[1024]; #if defined(_WIN32) _snprintf( rgchFullPath, sizeof( rgchFullPath ), "%s\\%s", rgchCWD, "controller.vdf" ); #elif defined(OSX) // hack for now, because we do not have utility functions available for finding the resource path // alternatively we could disable the SteamController init on OS X _snprintf( rgchFullPath, sizeof( rgchFullPath ), "%s/steamworksexample.app/Contents/Resources/%s", rgchCWD, "controller.vdf" ); #else _snprintf( rgchFullPath, sizeof( rgchFullPath ), "%s/%s", rgchCWD, "controller.vdf" ); #endif if( !SteamController()->Init( rgchFullPath ) ) { OutputDebugString( "SteamController()->Init() failed\n" ); Alert( "Fatal Error", "Steam Controller Init failed. Is controller.vdf in the current working directory?\n" ); return EXIT_FAILURE; } bool bUseVR = SteamUtils()->IsSteamRunningInVR(); const char *pchServerAddress, *pchLobbyID; ParseCommandLine( pchCmdLine, &pchServerAddress, &pchLobbyID, &bUseVR ); // do a DRM self check Steamworks_SelfCheck(); // init VR before we make the window // Construct a new instance of the game engine // bugbug jmccaskey - make screen resolution dynamic, maybe take it on command line? IGameEngine *pGameEngine = #if defined(_WIN32) new CGameEngineWin32( hInstance, nCmdShow, 1024, 768, bUseVR ); #elif defined(OSX) CreateGameEngineOSX(); #elif defined(SDL) CreateGameEngineSDL( bUseVR ); #else #error Need CreateGameEngine() #endif // This call will block and run until the game exits RunGameLoop( pGameEngine, pchServerAddress, pchLobbyID ); // Shutdown the SteamAPI SteamController()->Shutdown(); SteamAPI_Shutdown(); // Shutdown Steam CEG Steamworks_TermCEGLibrary(); // exit return EXIT_SUCCESS; }
SB_API ISteamClient *S_CALLTYPE SteamClient_() { return SteamClient(); }
void init(const std::vector<AchievementInfo>& achievementInfos) //const char *pchCmdLine, HINSTANCE hInstance, int nCmdShow) { g_AchievementInfosCopy = achievementInfos; for (size_t i = 0; i < achievementInfos.size(); ++i) { Achievement_t achievementData; achievementData.m_eAchievementID = i; achievementData.m_pchAchievementID = g_AchievementInfosCopy[i].id.c_str(); strncpy(achievementData.m_rgchName, g_AchievementInfosCopy[i].name.c_str(), 128); strncpy(achievementData.m_rgchDescription, g_AchievementInfosCopy[i].description.c_str(), 128); achievementData.m_bAchieved = false; achievementData.m_iIconImage = 0; g_Achievements.push_back(achievementData); } if (SteamAPI_RestartAppIfNecessary(k_uAppIdInvalid)) { // if Steam is not running or the game wasn't started through Steam, SteamAPI_RestartAppIfNecessary starts the // local Steam client and also launches this game again. // Once you get a public Steam AppID assigned for this game, you need to replace k_uAppIdInvalid with it and // removed steam_appid.txt from the game depot. AssertMessage(false, "SteamAPI_RestartAppIfNecessary failed"); } // Init Steam CEG if (!Steamworks_InitCEGLibrary()) { Utils::sleepMs(1000); if (!Steamworks_InitCEGLibrary()) // try twice - it may be a glitch in the network? { AssertMessage(false, "Steam must be running to play this game (InitDrmLibrary() failed)."); } } // Initialize SteamAPI, if this fails we bail out since we depend on Steam for lots of stuff. // You don't necessarily have to though if you write your code to check whether all the Steam // interfaces are NULL before using them and provide alternate paths when they are unavailable. // // This will also load the in-game steam overlay dll into your process. That dll is normally // injected by steam when it launches games, but by calling this you cause it to always load, // even when not launched via steam. if (!SteamAPI_Init()) { Utils::sleepMs(1000); if (!SteamAPI_Init()) { AssertMessage(false, "Steam must be running to play this game (SteamAPI_Init() failed).\n"); } } // Create the SteamAchievements object if Steam was successfully initialized g_SteamAchievements = new CSteamAchievements(&g_Achievements[0], g_Achievements.size()); bool res = g_SteamAchievements->RequestStats(); if (!res) { Utils::sleepMs(1000); res = g_SteamAchievements->RequestStats(); if (!res) { AssertMessage(false, "Could not get stats from Steam.\nPlease check that your Internet connection is working correctly and that Steam is up.\n"); } } // set our debug handler SteamClient()->SetWarningMessageHook(&SteamAPIDebugTextHook); // Tell Steam where it's overlay should show notification dialogs, this can be top right, top left, // bottom right, bottom left. The default position is the bottom left if you don't call this. // Generally you should use the default and not call this as users will be most comfortable with // the default position. The API is provided in case the bottom right creates a serious conflict // with important UI in your game. SteamUtils()->SetOverlayNotificationPosition(k_EPositionTopRight); // Ensure that the user has logged into Steam. This will always return true if the game is launched // from Steam, but if Steam is at the login prompt when you run your game from the debugger, it // will return false. if (!SteamUser()->BLoggedOn()) { Utils::sleepMs(1000); if (!SteamUser()->BLoggedOn()) { AssertMessage(false, "Steam user must be logged in to play this game (SteamUser()->BLoggedOn() returned false).\n"); } } // We are going to use the controller interface, initialize it, which is a seperate step as it // create a new thread in the game proc and we don't want to force that on games that don't // have native Steam controller implementations #ifdef USES_LINUX std::string rgchCWDstr = Utils::convertWStringToString(Utils::getCurrentDirectoryUnicode(), true); const char* rgchCWD = rgchCWDstr.c_str(); #else char rgchCWD[1024]; _getcwd( rgchCWD, sizeof( rgchCWD ) ); #endif char rgchFullPath[1024]; #if defined(_WIN32) _snprintf(rgchFullPath, sizeof(rgchFullPath), "%s\\%s", rgchCWD, "controller.vdf");//.c_str() #elif defined(OSX) // hack for now, because we do not have utility functions available for finding the resource path // alternatively we could disable the SteamController init on OS X _snprintf(rgchFullPath, sizeof(rgchFullPath), "%s/steamworksexample.app/Contents/Resources/%s", rgchCWD, "controller.vdf"); #else _snprintf(rgchFullPath, sizeof(rgchFullPath), "%s/%s", rgchCWD, "controller.vdf"); #endif if (!SteamController()->Init(rgchFullPath)) { AssertMessage(false, "Steam Controller Init failed. Is controller.vdf in the current working directory?\n"); } /*bool bUseVR = SteamUtils()->IsSteamRunningInVR(); const char *pchServerAddress, *pchLobbyID; ParseCommandLine(pchCmdLine, &pchServerAddress, &pchLobbyID, &bUseVR);*/ // do a DRM self check Steamworks_SelfCheck(); // init VR before we make the window // Construct a new instance of the game engine // bugbug jmccaskey - make screen resolution dynamic, maybe take it on command line? /*IGameEngine *pGameEngine = #if defined(_WIN32) new CGameEngineWin32(hInstance, nCmdShow, 1024, 768, bUseVR); #elif defined(OSX) CreateGameEngineOSX(); #elif defined(SDL) CreateGameEngineSDL(bUseVR); #else #error Need CreateGameEngine() #endif*/ }
void C_ASW_Medal_Store::LoadMedalStore() { #if defined(NO_STEAM) AssertMsg( false, "SteamCloud not available." ); #else ISteamRemoteStorage *pRemoteStorage = SteamClient() ? ( ISteamRemoteStorage * )SteamClient()->GetISteamGenericInterface( SteamAPI_GetHSteamUser(), SteamAPI_GetHSteamPipe(), STEAMREMOTESTORAGE_INTERFACE_VERSION ) : NULL; ISteamUser *pSteamUser = steamapicontext ? steamapicontext->SteamUser() : NULL; if ( !pSteamUser ) return; char szMedalFile[ 256 ]; Q_snprintf( szMedalFile, sizeof( szMedalFile ), "cfg/clientc_%I64u.dat", pSteamUser->GetSteamID().ConvertToUint64() ); int len = Q_strlen( szMedalFile ); for ( int i = 0; i < len; i++ ) { if ( szMedalFile[ i ] == ':' ) szMedalFile[i] = '_'; } if ( asw_steam_cloud.GetBool() && pRemoteStorage ) { if ( !GetFileFromRemoteStorage( pRemoteStorage, "PersistentMarines.dat", szMedalFile ) ) { #ifdef _DEBUG Warning( "Failed to get client.dat from Steam Cloud.\n" ); #endif } } #endif // clear out the currently loaded medals, if any for (int i=0;i<ASW_NUM_MARINE_PROFILES;i++) { m_MarineMedals[i].Purge(); m_OfflineMarineMedals[i].Purge(); } m_PlayerMedals.Purge(); m_OfflinePlayerMedals.Purge(); m_bLoaded = true; FileHandle_t f = filesystem->Open( szMedalFile, "rb", "MOD" ); if ( !f ) return; // if we get here, it means the player has no clientc.dat file and therefore no medals int fileSize = filesystem->Size(f); char *file_buffer = (char*)MemAllocScratch(fileSize + 1); Assert(file_buffer); filesystem->Read(file_buffer, fileSize, f); // read into local buffer file_buffer[fileSize] = 0; // null terminate file as EOF filesystem->Close( f ); // close file after reading UTIL_DecodeICE( (unsigned char*)file_buffer, fileSize, g_ucMedalStoreEncryptionKey ); KeyValues *kv = new KeyValues( "CLIENTDAT" ); if ( !kv->LoadFromBuffer( "CLIENTDAT", file_buffer, filesystem ) ) { return; } MemFreeScratch(); m_bFoundNewClientDat = true; // pull out missions/campaigns/kills m_iMissionsCompleted = kv->GetInt("MC"); m_iCampaignsCompleted = kv->GetInt("CC"); m_iAliensKilled = kv->GetInt("AK"); m_iOfflineMissionsCompleted = kv->GetInt("OMC"); m_iOfflineCampaignsCompleted = kv->GetInt("OCC"); m_iOfflineAliensKilled = kv->GetInt("OAK"); m_iXP = kv->GetInt( "LPL" ); m_iPromotion = kv->GetInt( "LPP" ); // new equip m_NewEquipment.Purge(); KeyValues *pkvEquip = kv->FindKey("NEWEQUIP"); char buffer[64]; if ( pkvEquip ) { for ( KeyValues *pKey = pkvEquip->GetFirstSubKey(); pKey; pKey = pKey->GetNextKey() ) { m_NewEquipment.AddToTail( pKey->GetInt() ); } } // first subsection is player medals //KeyValues *pkvPlayerMedals = kv->GetFirstSubKey(); KeyValues *pkvPlayerMedals = kv->FindKey("LP"); int iMedalNum = 0; if (pkvPlayerMedals) { int iMedal = 0; while (iMedal != -1) { Q_snprintf(buffer, sizeof(buffer), "M%d", iMedalNum); iMedal = pkvPlayerMedals->GetInt(buffer, -1); if (iMedal != -1 && IsPlayerMedal(iMedal)) { m_PlayerMedals.AddToTail(iMedal); } iMedalNum++; } } // now go through each marine for (int i=0;i<ASW_NUM_MARINE_PROFILES;i++) { Q_snprintf(buffer, sizeof(buffer), "LA%d", i); KeyValues *pkvMarineMedals = kv->FindKey(buffer); if (pkvMarineMedals) { iMedalNum = 0; int iMedal = 0; while (iMedal != -1) { Q_snprintf(buffer, sizeof(buffer), "M%d", iMedalNum); iMedal = pkvMarineMedals->GetInt(buffer, -1); if (iMedal != -1 && !IsPlayerMedal(iMedal)) { m_MarineMedals[i].AddToTail(iMedal); } iMedalNum++; } } } // offline medal store pkvPlayerMedals = kv->FindKey("FP"); iMedalNum = 0; if (pkvPlayerMedals) { int iMedal = 0; while (iMedal != -1) { Q_snprintf(buffer, sizeof(buffer), "M%d", iMedalNum); iMedal = pkvPlayerMedals->GetInt(buffer, -1); if (iMedal != -1 && IsPlayerMedal(iMedal)) { m_OfflinePlayerMedals.AddToTail(iMedal); } iMedalNum++; } } // now go through each marine for (int i=0;i<ASW_NUM_MARINE_PROFILES;i++) { Q_snprintf(buffer, sizeof(buffer), "FA%d", i); KeyValues *pkvMarineMedals = kv->FindKey(buffer); if (pkvMarineMedals) { iMedalNum = 0; int iMedal = 0; while (iMedal != -1) { Q_snprintf(buffer, sizeof(buffer), "M%d", iMedalNum); iMedal = pkvMarineMedals->GetInt(buffer, -1); if (iMedal != -1 && !IsPlayerMedal(iMedal)) { m_OfflineMarineMedals[i].AddToTail(iMedal); } iMedalNum++; } } } }
bool C_ASW_Medal_Store::SaveMedalStore() { if ( !m_bLoaded ) return false; KeyValues *kv = new KeyValues( "CLIENTDAT" ); // output missions/campaigns/kills kv->SetInt("MC", m_iMissionsCompleted); kv->SetInt("CC", m_iCampaignsCompleted); kv->SetInt("AK", m_iAliensKilled); kv->SetInt("OMC", m_iOfflineMissionsCompleted); kv->SetInt("OCC", m_iOfflineCampaignsCompleted); kv->SetInt("OAK", m_iOfflineAliensKilled); kv->SetInt( "LPL", m_iXP ); kv->SetInt( "LPP", m_iPromotion ); KeyValues *pSubSection = new KeyValues("NEWEQUIP"); char buffer[64]; if (pSubSection) { for (int i=0;i<m_NewEquipment.Count();i++) { pSubSection->SetInt( "EQUIP", m_NewEquipment[i]); } kv->AddSubKey(pSubSection); } // output player medals pSubSection = new KeyValues("LP"); if (pSubSection) { for (int i=0;i<m_PlayerMedals.Count();i++) { Q_snprintf(buffer, sizeof(buffer), "M%d", i); pSubSection->SetInt(buffer, m_PlayerMedals[i]); } kv->AddSubKey(pSubSection); } for (int k=0;k<ASW_NUM_MARINE_PROFILES;k++) { Q_snprintf(buffer, sizeof(buffer), "LA%d", k); pSubSection = new KeyValues(buffer); if (pSubSection) { for (int i=0;i<m_MarineMedals[k].Count();i++) { Q_snprintf(buffer, sizeof(buffer), "M%d", i); pSubSection->SetInt(buffer, m_MarineMedals[k][i]); } kv->AddSubKey(pSubSection); } } // offline medal store pSubSection = new KeyValues("FP"); if (pSubSection) { for (int i=0;i<m_OfflinePlayerMedals.Count();i++) { Q_snprintf(buffer, sizeof(buffer), "M%d", i); pSubSection->SetInt(buffer, m_OfflinePlayerMedals[i]); } kv->AddSubKey(pSubSection); } for (int k=0;k<ASW_NUM_MARINE_PROFILES;k++) { Q_snprintf(buffer, sizeof(buffer), "FA%d", k); pSubSection = new KeyValues(buffer); if (pSubSection) { for (int i=0;i<m_OfflineMarineMedals[k].Count();i++) { Q_snprintf(buffer, sizeof(buffer), "M%d", i); pSubSection->SetInt(buffer, m_OfflineMarineMedals[k][i]); } kv->AddSubKey(pSubSection); } } CUtlBuffer buf; //( 0, 0, CUtlBuffer::TEXT_BUFFER ); kv->RecursiveSaveToFile( buf, 0 ); // pad buffer with zeroes to make a multiple of 8 int nExtra = buf.TellPut() % 8; while ( nExtra != 0 && nExtra < 8 ) { buf.PutChar( 0 ); nExtra++; } UTIL_EncodeICE( (unsigned char*) buf.Base(), buf.TellPut(), g_ucMedalStoreEncryptionKey ); ISteamUser *pSteamUser = steamapicontext ? steamapicontext->SteamUser() : NULL; if ( !pSteamUser ) return false; char szMedalFile[ 256 ]; Q_snprintf( szMedalFile, sizeof( szMedalFile ), "cfg/clientc_%I64u.dat", pSteamUser->GetSteamID().ConvertToUint64() ); int len = Q_strlen( szMedalFile ); for ( int i = 0; i < len; i++ ) { if ( szMedalFile[ i ] == ':' ) szMedalFile[i] = '_'; } bool bResult = filesystem->WriteFile( szMedalFile, "MOD", buf ); if ( bResult ) { #if defined(NO_STEAM) AssertMsg( false, "SteamCloud not available." ); #else ISteamRemoteStorage *pRemoteStorage = SteamClient() ? ( ISteamRemoteStorage * )SteamClient()->GetISteamGenericInterface( SteamAPI_GetHSteamUser(), SteamAPI_GetHSteamPipe(), STEAMREMOTESTORAGE_INTERFACE_VERSION ) : NULL; if ( asw_steam_cloud.GetBool() && pRemoteStorage ) { WriteFileToRemoteStorage( pRemoteStorage, "PersistentMarines.dat", szMedalFile ); } #endif } return bResult; }