#include "Achievements.h" #include "skse64/GameMenus.h" #include "skse64/GameEvents.h" #include "steam\steam_api.h" #include #include class InitSteamOnEvent : public BSTEventSink { public: virtual ~InitSteamOnEvent() {} virtual EventResult ReceiveEvent(MenuOpenCloseEvent * evn, EventDispatcher * dispatcher) { if (std::strcmp(evn->menuName.data, "Main Menu")) { _MESSAGE("Main menu opened, trying to init steam API."); Achievements::startSteam(); } return EventResult::kEvent_Continue; } }; namespace Achievements { bool setAchievementUnlocked(StaticFunctionTag* tag, BSFixedString achievement) { return singleton->setAchievementUnlocked(achievement.data); } void registerMainMenuEvent() { MenuManager * mm = MenuManager::GetSingleton(); if (mm) { mm->MenuOpenCloseEventDispatcher()->AddEventSink(new InitSteamOnEvent()); } else { _MESSAGE("Failed to register SKSE menuEventHandler!"); } } void steamInit(StaticFunctionTag* tag) { startSteam(); } void startSteam() { try { if (singleton.get() == nullptr) { SteamAPI_Shutdown(); SetEnvironmentVariable("SteamAppID", "933480"); SetEnvironmentVariable("SteamGameId", "933480"); bool success = SteamAPI_Init(); if (success) _MESSAGE("Steam api init was successfull"); else _MESSAGE("Error while initializing the steam api"); singleton.swap(std::make_unique()); singleton->start(); } else { _MESSAGE("Already initialized steam api, skipping it"); } } catch (const std::exception& ex) { std::string msg = "Exception while initializing the Steam API, steam achievements will not be available: " + std::string(ex.what()); _MESSAGE(msg.c_str()); } } bool RegisterFuncs(VMClassRegistry * registry) { registry->RegisterFunction(new NativeFunction1("UnlockAchievement", "Game", Achievements::setAchievementUnlocked, registry)); registry->RegisterFunction( new NativeFunction0("SteamInit", "Game", Achievements::steamInit, registry)); Achievements::registerMainMenuEvent(); return true; } AchievementHolder::AchievementHolder() : stats(SteamUserStats()), callback(this, &AchievementHolder::onUserStatsReceived) { } void AchievementHolder::onUserStatsReceived(UserStatsReceived_t * event) { try { std::string msg = "User id: " + std::to_string(event->m_steamIDUser.ConvertToUint64()) + ", game id: " + std::to_string(event->m_nGameID) + ", success state: " + std::to_string(event->m_eResult); _MESSAGE(msg.c_str()); uint32 achievementCount = this->stats->GetNumAchievements(); msg = "There are " + std::to_string(achievementCount) + " achievements"; _MESSAGE(msg.c_str()); } catch (const std::exception& ex) { std::string msg = "Exception during steam callback: onUserStatsReceived. Failed to print data: " + std::string(ex.what()); _MESSAGE(msg.c_str()); } } bool AchievementHolder::setAchievementUnlocked(const char * achievementName) { std::string msg = "Unlocking achievement: " + std::string(achievementName); _MESSAGE(msg.c_str()); bool success = this->stats->SetAchievement(achievementName); if (!success) { _MESSAGE("Error while unlocking achievement"); return false; } success = this->stats->StoreStats(); if (!success) { _MESSAGE("Error while storing unlocked achievement"); } return success; } void AchievementHolder::start() { this->stats->RequestCurrentStats(); } }