1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
#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<pair<uint16_t, uint16_t>>) override;
MVariant<P2PNetworkingPeerId, HostAddressWithPort> pullPendingJoin() override;
Maybe<pair<String, RpcPromiseKeeper<P2PJoinRequestReply>>> pullJoinRequest() override;
void setAcceptingP2PConnections(bool acceptingP2PConnections) override;
List<P2PSocketUPtr> acceptP2PConnections() override;
void update() override;
Either<String, P2PSocketUPtr> 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<JoinUnavailable, JoinLocal, JoinRemote> JoinLocation;
#ifdef STAR_ENABLE_STEAM_INTEGRATION
struct SteamP2PSocket : P2PSocket {
SteamP2PSocket() = default;
~SteamP2PSocket();
bool isOpen() override;
bool sendMessage(ByteArray const& message) override;
Maybe<ByteArray> receiveMessage() override;
Mutex mutex;
PcP2PNetworkingService* parent = nullptr;
CSteamID steamId = CSteamID();
Deque<ByteArray> incoming;
bool connected = false;
};
unique_ptr<SteamP2PSocket> 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<ByteArray> receiveMessage() override;
Mutex mutex;
PcP2PNetworkingService* parent = nullptr;
DiscordSocketMode mode = DiscordSocketMode::Disconnected;
discord::LobbyId lobbyId = {};
discord::UserId remoteUserId;
Deque<ByteArray> 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<P2PSocketUPtr> m_pendingIncomingConnections;
MVariant<P2PNetworkingPeerId, HostAddressWithPort> m_pendingJoin;
#ifdef STAR_ENABLE_STEAM_INTEGRATION
HashMap<uint64, SteamP2PSocket*> m_steamOpenSockets;
#endif
#ifdef STAR_ENABLE_DISCORD_INTEGRATION
List<pair<discord::UserId, String>> m_discordJoinRequests;
List<pair<discord::UserId, RpcPromise<P2PJoinRequestReply>>> m_pendingDiscordJoinRequests;
HashMap<discord::UserId, DiscordP2PSocket*> m_discordOpenSockets;
String m_discordActivityTitle;
String m_discordActivityDetails;
int64_t m_discordActivityStartTime = 0;
Maybe<pair<uint16_t, uint16_t>> m_discordPartySize;
bool m_discordForceUpdateActivity = false;
bool m_discordUpdatingActivity = false;
Maybe<pair<discord::LobbyId, String>> 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
};
}
|