#pragma once #include "StarPlatformServices_pc.hpp" #include "StarAlgorithm.hpp" #include "StarThread.hpp" #include "StarStrongTypedef.hpp" #include "StarRpcPromise.hpp" namespace Star { STAR_CLASS(PcP2PNetworkingService); class PcP2PNetworkingService : public P2PNetworkingService { public: PcP2PNetworkingService(PcPlatformServicesStatePtr state); ~PcP2PNetworkingService(); void setJoinUnavailable() override; void setJoinLocal(uint32_t capacity) override; void setJoinRemote(HostAddressWithPort location) override; void setActivityData(const char* title, const char* details, int64_t startTime, Maybe>) override; MVariant pullPendingJoin() override; Maybe>> pullJoinRequest() override; void setAcceptingP2PConnections(bool acceptingP2PConnections) override; List acceptP2PConnections() override; void update() override; Either connectToPeer(P2PNetworkingPeerId peerId) override; void addPendingJoin(String connectionString); private: strong_typedef(Empty, JoinUnavailable); struct JoinLocal { bool operator==(JoinLocal const& rhs) const { return capacity == rhs.capacity; }; uint32_t capacity; }; strong_typedef(HostAddressWithPort, JoinRemote); typedef Variant JoinLocation; #ifdef STAR_ENABLE_STEAM_INTEGRATION struct SteamP2PSocket : P2PSocket { SteamP2PSocket() = default; ~SteamP2PSocket(); bool isOpen() override; bool sendMessage(ByteArray const& message) override; Maybe receiveMessage() override; Mutex mutex; PcP2PNetworkingService* parent = nullptr; CSteamID steamId = CSteamID(); Deque incoming; bool connected = false; }; unique_ptr createSteamP2PSocket(CSteamID steamId); STEAM_CALLBACK(PcP2PNetworkingService, steamOnConnectionFailure, P2PSessionConnectFail_t, m_callbackConnectionFailure); STEAM_CALLBACK(PcP2PNetworkingService, steamOnJoinRequested, GameRichPresenceJoinRequested_t, m_callbackJoinRequested); STEAM_CALLBACK(PcP2PNetworkingService, steamOnSessionRequest, P2PSessionRequest_t, m_callbackSessionRequest); void steamCloseSocket(SteamP2PSocket* socket); void steamReceiveAll(); #endif #ifdef STAR_ENABLE_DISCORD_INTEGRATION enum class DiscordSocketMode { Startup, Connected, Disconnected }; struct DiscordP2PSocket : P2PSocket { DiscordP2PSocket() = default; ~DiscordP2PSocket(); bool isOpen() override; bool sendMessage(ByteArray const& message) override; Maybe receiveMessage() override; Mutex mutex; PcP2PNetworkingService* parent = nullptr; DiscordSocketMode mode = DiscordSocketMode::Disconnected; discord::LobbyId lobbyId = {}; discord::UserId remoteUserId; Deque incoming; }; P2PSocketUPtr discordConnectRemote(discord::UserId remoteUserId, discord::LobbyId lobbyId, String const& lobbySecret); void discordCloseSocket(DiscordP2PSocket* socket); void discordOnReceiveMessage(discord::LobbyId lobbyId, discord::UserId userId, discord::NetworkChannelId channel, uint8_t* data, uint32_t size); void discordOnLobbyMemberConnect(discord::LobbyId lobbyId, discord::UserId userId); void discordOnLobbyMemberUpdate(discord::LobbyId lobbyId, discord::UserId userId); void discordOnLobbyMemberDisconnect(discord::LobbyId lobbyId, discord::UserId userId); #endif void setJoinLocation(JoinLocation joinLocation); PcPlatformServicesStatePtr m_state; Mutex m_mutex; JoinLocation m_joinLocation; bool m_acceptingP2PConnections = false; List m_pendingIncomingConnections; MVariant m_pendingJoin; #ifdef STAR_ENABLE_STEAM_INTEGRATION HashMap m_steamOpenSockets; #endif #ifdef STAR_ENABLE_DISCORD_INTEGRATION List> m_discordJoinRequests; List>> m_pendingDiscordJoinRequests; HashMap m_discordOpenSockets; String m_discordActivityTitle; String m_discordActivityDetails; int64_t m_discordActivityStartTime = 0; Maybe> m_discordPartySize; bool m_discordForceUpdateActivity = false; bool m_discordUpdatingActivity = false; Maybe> m_discordServerLobby = {}; int m_discordOnActivityJoinToken = 0; int m_discordOnActivityRequestToken = 0; int m_discordOnReceiveMessage = 0; int m_discordOnLobbyMemberConnect = 0; int m_discordOnLobbyMemberUpdate = 0; int m_discordOnLobbyMemberDisconnect = 0; #endif }; }