#include "StarLogging.hpp" #include "StarPlatformServices_pc.hpp" #include "StarP2PNetworkingService_pc.hpp" #ifdef STAR_ENABLE_STEAM_INTEGRATION #include "StarStatisticsService_pc_steam.hpp" #include "StarUserGeneratedContentService_pc_steam.hpp" #include "StarDesktopService_pc_steam.hpp" #endif namespace Star { #ifdef STAR_ENABLE_DISCORD_INTEGRATION uint64_t const DiscordClientId = 467102538278109224; #endif PcPlatformServicesState::PcPlatformServicesState() #ifdef STAR_ENABLE_STEAM_INTEGRATION : callbackGameOverlayActivated(this, &PcPlatformServicesState::onGameOverlayActivated) { #else { #endif #ifdef STAR_ENABLE_STEAM_INTEGRATION if (SteamAPI_Init()) { steamAvailable = true; Logger::info("Initialized Steam platform services"); } else { Logger::info("Failed to initialize Steam platform services"); } #endif #ifdef STAR_ENABLE_DISCORD_INTEGRATION static int64_t const DiscordEventSleep = 3; discord::Core* discordCorePtr = nullptr; discord::Result res = discord::Core::Create(DiscordClientId, DiscordCreateFlags_NoRequireDiscord, &discordCorePtr); if (res == discord::Result::Ok && discordCorePtr) { discordCore.reset(discordCorePtr); discordAvailable = true; discordCore->UserManager().OnCurrentUserUpdate.Connect([this](){ discord::User user; auto res = discordCore->UserManager().GetCurrentUser(&user); if (res != discord::Result::Ok) Logger::error("Could not get current Discord user. (err {})", (int)res); else discordCurrentUser = user; }); } else { Logger::error("Failed to instantiate Discord core (err {})", (int)res); } if (discordAvailable) { MutexLocker locker(discordMutex); discordCore->SetLogHook(discord::LogLevel::Info, [](discord::LogLevel level, char const* msg) { if (level == discord::LogLevel::Debug) Logger::debug("[Discord]: {}", msg); else if (level == discord::LogLevel::Error) Logger::debug("[Discord]: {}", msg); else if (level == discord::LogLevel::Info) Logger::info("[Discord]: {}", msg); else if (level == discord::LogLevel::Warn) Logger::warn("[Discord]: {}", msg); }); discordEventShutdown = false; discordEventThread = Thread::invoke("PcPlatformServices::discordEventThread", [this]() { while (!discordEventShutdown) { { MutexLocker locker(discordMutex); discordCore->RunCallbacks(); discordCore->LobbyManager().FlushNetwork(); } Thread::sleep(DiscordEventSleep); } }); Logger::info("Initialized Discord platform services"); } else { Logger::info("Was not able to authenticate with Discord and create all components, Discord services will be unavailable"); } #endif } PcPlatformServicesState::~PcPlatformServicesState() { #ifdef STAR_ENABLE_DISCORD_INTEGRATION if (discordAvailable) { discordEventShutdown = true; discordEventThread.finish(); } #endif } #ifdef STAR_ENABLE_STEAM_INTEGRATION void PcPlatformServicesState::onGameOverlayActivated(GameOverlayActivated_t* callback) { overlayActive = callback->m_bActive; } #endif PcPlatformServicesUPtr PcPlatformServices::create([[maybe_unused]] String const& path, StringList platformArguments) { auto services = unique_ptr(new PcPlatformServices); services->m_state = make_shared(); bool provideP2PNetworking = false; #ifdef STAR_ENABLE_STEAM_INTEGRATION provideP2PNetworking |= services->m_state->steamAvailable; #endif #ifdef STAR_ENABLE_DISCORD_INTEGRATION provideP2PNetworking |= services->m_state->discordAvailable; #endif if (provideP2PNetworking) { auto p2pNetworkingService = make_shared(services->m_state); for (auto& argument : platformArguments) { if (argument.beginsWith("+platform:connect:")) { Logger::info("PC platform services joining from command line argument '{}'", argument); p2pNetworkingService->addPendingJoin(std::move(argument)); } else { throw ApplicationException::format("Unrecognized PC platform services command line argument '{}'", argument); } } services->m_p2pNetworkingService = p2pNetworkingService; } #ifdef STAR_ENABLE_STEAM_INTEGRATION if (services->m_state->steamAvailable) { services->m_statisticsService = make_shared(services->m_state); services->m_userGeneratedContentService = make_shared(services->m_state); services->m_desktopService = make_shared(services->m_state); } #endif #ifdef STAR_ENABLE_DISCORD_INTEGRATION MutexLocker discordLocker(services->m_state->discordMutex); if (services->m_state->discordAvailable) { Logger::debug("Registering Starbound to Discord at path: {}", path); services->m_state->discordCore->ActivityManager().RegisterCommand(path.utf8Ptr()); } #endif return services; } StatisticsServicePtr PcPlatformServices::statisticsService() const { return m_statisticsService; } P2PNetworkingServicePtr PcPlatformServices::p2pNetworkingService() const { return m_p2pNetworkingService; } UserGeneratedContentServicePtr PcPlatformServices::userGeneratedContentService() const { return m_userGeneratedContentService; } DesktopServicePtr PcPlatformServices::desktopService() const { return m_desktopService; } bool PcPlatformServices::overlayActive() const { return m_state->overlayActive; } void PcPlatformServices::update() { #ifdef STAR_ENABLE_STEAM_INTEGRATION SteamAPI_RunCallbacks(); #endif } }