优化网络消息处理的睡眠时间,减少CPU占用;扩展连接配置以支持更多参数

This commit is contained in:
Ayndpa
2025-11-19 13:47:01 +08:00
parent f2fde172e1
commit 3896a91433
3 changed files with 186 additions and 89 deletions

View File

@@ -52,7 +52,7 @@ void SteamMessageHandler::run() {
pollMessages(); pollMessages();
// Sleep a bit to avoid busy loop // Sleep a bit to avoid busy loop
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(1));
} }
} }

View File

@@ -2,78 +2,111 @@
#include <iostream> #include <iostream>
#include <algorithm> #include <algorithm>
SteamNetworkingManager* SteamNetworkingManager::instance = nullptr; SteamNetworkingManager *SteamNetworkingManager::instance = nullptr;
SteamNetworkingConfigValue_t g_connectionConfig;
// Static callback function // Static callback function
void SteamNetworkingManager::OnSteamNetConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t *pInfo) { void SteamNetworkingManager::OnSteamNetConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t *pInfo)
if (instance) { {
if (instance)
{
instance->handleConnectionStatusChanged(pInfo); instance->handleConnectionStatusChanged(pInfo);
} }
} }
SteamFriendsCallbacks::SteamFriendsCallbacks(SteamNetworkingManager* manager) : manager_(manager) { SteamFriendsCallbacks::SteamFriendsCallbacks(SteamNetworkingManager *manager) : manager_(manager)
{
std::cout << "SteamFriendsCallbacks constructor called" << std::endl; std::cout << "SteamFriendsCallbacks constructor called" << std::endl;
} }
void SteamFriendsCallbacks::OnGameRichPresenceJoinRequested(GameRichPresenceJoinRequested_t *pCallback) { void SteamFriendsCallbacks::OnGameRichPresenceJoinRequested(GameRichPresenceJoinRequested_t *pCallback)
{
std::cout << "GameRichPresenceJoinRequested received" << std::endl; std::cout << "GameRichPresenceJoinRequested received" << std::endl;
if (manager_) { if (manager_)
const char* connectStr = pCallback->m_rgchConnect; {
const char *connectStr = pCallback->m_rgchConnect;
std::cout << "Connect string: '" << (connectStr ? connectStr : "null") << "'" << std::endl; std::cout << "Connect string: '" << (connectStr ? connectStr : "null") << "'" << std::endl;
if (connectStr && connectStr[0] != '\0') { if (connectStr && connectStr[0] != '\0')
try { {
try
{
uint64 id = std::stoull(connectStr); uint64 id = std::stoull(connectStr);
std::string str = connectStr; std::string str = connectStr;
std::cout << "Parsed ID: " << id << std::endl; std::cout << "Parsed ID: " << id << std::endl;
if (str.find("7656119") == 0) { if (str.find("7656119") == 0)
{
// It's a Steam ID, join host directly // It's a Steam ID, join host directly
std::cout << "Parsed Steam ID: " << id << ", joining host" << std::endl; std::cout << "Parsed Steam ID: " << id << ", joining host" << std::endl;
if (!manager_->isHost() && !manager_->isConnected()) { if (!manager_->isHost() && !manager_->isConnected())
{
manager_->joinHost(id); manager_->joinHost(id);
// Start TCP Server if dependencies are set // Start TCP Server if dependencies are set
if (manager_->server_ && !(*manager_->server_)) { if (manager_->server_ && !(*manager_->server_))
{
*manager_->server_ = std::make_unique<TCPServer>(8888, manager_); *manager_->server_ = std::make_unique<TCPServer>(8888, manager_);
if (!(*manager_->server_)->start()) { if (!(*manager_->server_)->start())
{
std::cerr << "Failed to start TCP server" << std::endl; std::cerr << "Failed to start TCP server" << std::endl;
} }
} }
} else { }
else
{
std::cout << "Already host or connected, ignoring join request" << std::endl; std::cout << "Already host or connected, ignoring join request" << std::endl;
} }
} else { }
else
{
// Assume it's a lobby ID // Assume it's a lobby ID
CSteamID lobbySteamID(id); CSteamID lobbySteamID(id);
std::cout << "Parsed lobby ID: " << id << std::endl; std::cout << "Parsed lobby ID: " << id << std::endl;
if (!manager_->isHost() && !manager_->isConnected()) { if (!manager_->isHost() && !manager_->isConnected())
{
std::cout << "Joining lobby from invite: " << id << std::endl; std::cout << "Joining lobby from invite: " << id << std::endl;
manager_->joinLobby(lobbySteamID); manager_->joinLobby(lobbySteamID);
} else { }
else
{
std::cout << "Already host or connected, ignoring invite" << std::endl; std::cout << "Already host or connected, ignoring invite" << std::endl;
} }
} }
} catch (const std::exception& e) { }
catch (const std::exception &e)
{
std::cerr << "Failed to parse connect string: " << connectStr << " error: " << e.what() << std::endl; std::cerr << "Failed to parse connect string: " << connectStr << " error: " << e.what() << std::endl;
} }
} else { }
else
{
std::cerr << "Empty connect string in join request" << std::endl; std::cerr << "Empty connect string in join request" << std::endl;
} }
} else { }
else
{
std::cout << "Manager is null" << std::endl; std::cout << "Manager is null" << std::endl;
} }
} }
void SteamFriendsCallbacks::OnGameLobbyJoinRequested(GameLobbyJoinRequested_t *pCallback) { void SteamFriendsCallbacks::OnGameLobbyJoinRequested(GameLobbyJoinRequested_t *pCallback)
{
std::cout << "GameLobbyJoinRequested received" << std::endl; std::cout << "GameLobbyJoinRequested received" << std::endl;
if (manager_) { if (manager_)
{
CSteamID lobbyID = pCallback->m_steamIDLobby; CSteamID lobbyID = pCallback->m_steamIDLobby;
std::cout << "Lobby ID: " << lobbyID.ConvertToUint64() << std::endl; std::cout << "Lobby ID: " << lobbyID.ConvertToUint64() << std::endl;
if (!manager_->isHost() && !manager_->isConnected()) { if (!manager_->isHost() && !manager_->isConnected())
{
std::cout << "Joining lobby from request: " << lobbyID.ConvertToUint64() << std::endl; std::cout << "Joining lobby from request: " << lobbyID.ConvertToUint64() << std::endl;
manager_->joinLobby(lobbyID); manager_->joinLobby(lobbyID);
} else { }
else
{
std::cout << "Already host or connected, ignoring lobby join request" << std::endl; std::cout << "Already host or connected, ignoring lobby join request" << std::endl;
} }
} else { }
else
{
std::cout << "Manager is null" << std::endl; std::cout << "Manager is null" << std::endl;
} }
} }
@@ -82,13 +115,16 @@ SteamNetworkingManager::SteamNetworkingManager()
: m_pInterface(nullptr), hListenSock(k_HSteamListenSocket_Invalid), g_isHost(false), g_isClient(false), g_isConnected(false), : m_pInterface(nullptr), hListenSock(k_HSteamListenSocket_Invalid), g_isHost(false), g_isClient(false), g_isConnected(false),
g_hConnection(k_HSteamNetConnection_Invalid), g_retryCount(0), g_currentVirtualPort(0), g_hConnection(k_HSteamNetConnection_Invalid), g_retryCount(0), g_currentVirtualPort(0),
io_context_(nullptr), clientMap_(nullptr), clientMutex_(nullptr), server_(nullptr), localPort_(nullptr), messageHandler_(nullptr), io_context_(nullptr), clientMap_(nullptr), clientMutex_(nullptr), server_(nullptr), localPort_(nullptr), messageHandler_(nullptr),
steamFriendsCallbacks(nullptr), steamMatchmakingCallbacks(nullptr), currentLobby(k_steamIDNil) { steamFriendsCallbacks(nullptr), steamMatchmakingCallbacks(nullptr), currentLobby(k_steamIDNil)
{
// Initialize connection config // Initialize connection config
g_connectionConfig[0].SetInt32(k_ESteamNetworkingConfig_TimeoutInitial, 10000); g_connectionConfig[0].SetInt32(k_ESteamNetworkingConfig_P2P_Transport_ICE_Enable, k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_All);
g_connectionConfig[1].SetInt32(k_ESteamNetworkingConfig_NagleTime, 0); g_connectionConfig[1].SetInt32(k_ESteamNetworkingConfig_P2P_Transport_SDR_Penalty, 300);
std::cout << "Initialized SteamNetworkingManager" << std::endl;
} }
SteamNetworkingManager::~SteamNetworkingManager() { SteamNetworkingManager::~SteamNetworkingManager()
{
stopMessageHandler(); stopMessageHandler();
delete messageHandler_; delete messageHandler_;
delete steamFriendsCallbacks; delete steamFriendsCallbacks;
@@ -96,9 +132,11 @@ SteamNetworkingManager::~SteamNetworkingManager() {
shutdown(); shutdown();
} }
bool SteamNetworkingManager::initialize() { bool SteamNetworkingManager::initialize()
{
instance = this; instance = this;
if (!SteamAPI_Init()) { if (!SteamAPI_Init())
{
std::cerr << "Failed to initialize Steam API" << std::endl; std::cerr << "Failed to initialize Steam API" << std::endl;
return false; return false;
} }
@@ -121,21 +159,25 @@ bool SteamNetworkingManager::initialize() {
// Get friends list // Get friends list
int friendCount = SteamFriends()->GetFriendCount(k_EFriendFlagAll); int friendCount = SteamFriends()->GetFriendCount(k_EFriendFlagAll);
for (int i = 0; i < friendCount; ++i) { for (int i = 0; i < friendCount; ++i)
{
CSteamID friendID = SteamFriends()->GetFriendByIndex(i, k_EFriendFlagAll); CSteamID friendID = SteamFriends()->GetFriendByIndex(i, k_EFriendFlagAll);
const char* name = SteamFriends()->GetFriendPersonaName(friendID); const char *name = SteamFriends()->GetFriendPersonaName(friendID);
friendsList.push_back({friendID, name}); friendsList.push_back({friendID, name});
} }
return true; return true;
} }
void SteamNetworkingManager::shutdown() { void SteamNetworkingManager::shutdown()
{
leaveLobby(); leaveLobby();
if (g_hConnection != k_HSteamNetConnection_Invalid) { if (g_hConnection != k_HSteamNetConnection_Invalid)
{
m_pInterface->CloseConnection(g_hConnection, 0, nullptr, false); m_pInterface->CloseConnection(g_hConnection, 0, nullptr, false);
} }
if (hListenSock != k_HSteamListenSocket_Invalid) { if (hListenSock != k_HSteamListenSocket_Invalid)
{
m_pInterface->CloseListenSocket(hListenSock); m_pInterface->CloseListenSocket(hListenSock);
} }
// Clear Rich Presence on shutdown // Clear Rich Presence on shutdown
@@ -143,9 +185,11 @@ void SteamNetworkingManager::shutdown() {
SteamAPI_Shutdown(); SteamAPI_Shutdown();
} }
bool SteamNetworkingManager::createLobby() { bool SteamNetworkingManager::createLobby()
{
SteamAPICall_t hSteamAPICall = SteamMatchmaking()->CreateLobby(k_ELobbyTypePublic, 4); SteamAPICall_t hSteamAPICall = SteamMatchmaking()->CreateLobby(k_ELobbyTypePublic, 4);
if (hSteamAPICall == k_uAPICallInvalid) { if (hSteamAPICall == k_uAPICallInvalid)
{
std::cerr << "Failed to create lobby" << std::endl; std::cerr << "Failed to create lobby" << std::endl;
return false; return false;
} }
@@ -153,17 +197,21 @@ bool SteamNetworkingManager::createLobby() {
return true; return true;
} }
void SteamNetworkingManager::leaveLobby() { void SteamNetworkingManager::leaveLobby()
if (currentLobby != k_steamIDNil) { {
if (currentLobby != k_steamIDNil)
{
SteamMatchmaking()->LeaveLobby(currentLobby); SteamMatchmaking()->LeaveLobby(currentLobby);
currentLobby = k_steamIDNil; currentLobby = k_steamIDNil;
} }
} }
bool SteamNetworkingManager::searchLobbies() { bool SteamNetworkingManager::searchLobbies()
{
lobbies.clear(); lobbies.clear();
SteamAPICall_t hSteamAPICall = SteamMatchmaking()->RequestLobbyList(); SteamAPICall_t hSteamAPICall = SteamMatchmaking()->RequestLobbyList();
if (hSteamAPICall == k_uAPICallInvalid) { if (hSteamAPICall == k_uAPICallInvalid)
{
std::cerr << "Failed to request lobby list" << std::endl; std::cerr << "Failed to request lobby list" << std::endl;
return false; return false;
} }
@@ -171,8 +219,10 @@ bool SteamNetworkingManager::searchLobbies() {
return true; return true;
} }
bool SteamNetworkingManager::joinLobby(CSteamID lobbyID) { bool SteamNetworkingManager::joinLobby(CSteamID lobbyID)
if (SteamMatchmaking()->JoinLobby(lobbyID) != k_EResultOK) { {
if (SteamMatchmaking()->JoinLobby(lobbyID) != k_EResultOK)
{
std::cerr << "Failed to join lobby" << std::endl; std::cerr << "Failed to join lobby" << std::endl;
return false; return false;
} }
@@ -180,25 +230,32 @@ bool SteamNetworkingManager::joinLobby(CSteamID lobbyID) {
return true; return true;
} }
bool SteamNetworkingManager::startHosting() { bool SteamNetworkingManager::startHosting()
if (!createLobby()) { {
if (!createLobby())
{
return false; return false;
} }
hListenSock = m_pInterface->CreateListenSocketP2P(0, 0, nullptr); hListenSock = m_pInterface->CreateListenSocketP2P(0, 0, g_connectionConfig);
if (hListenSock != k_HSteamListenSocket_Invalid) { if (hListenSock != k_HSteamListenSocket_Invalid)
{
g_isHost = true; g_isHost = true;
std::cout << "Created listen socket for hosting game room" << std::endl; std::cout << "Created listen socket for hosting game room" << std::endl;
// Rich Presence is set in OnLobbyCreated callback // Rich Presence is set in OnLobbyCreated callback
return true; return true;
} else { }
else
{
std::cerr << "Failed to create listen socket for hosting" << std::endl; std::cerr << "Failed to create listen socket for hosting" << std::endl;
leaveLobby(); leaveLobby();
return false; return false;
} }
} }
void SteamNetworkingManager::stopHosting() { void SteamNetworkingManager::stopHosting()
if (hListenSock != k_HSteamListenSocket_Invalid) { {
if (hListenSock != k_HSteamListenSocket_Invalid)
{
m_pInterface->CloseListenSocket(hListenSock); m_pInterface->CloseListenSocket(hListenSock);
hListenSock = k_HSteamListenSocket_Invalid; hListenSock = k_HSteamListenSocket_Invalid;
} }
@@ -206,7 +263,8 @@ void SteamNetworkingManager::stopHosting() {
g_isHost = false; g_isHost = false;
} }
bool SteamNetworkingManager::joinHost(uint64 hostID) { bool SteamNetworkingManager::joinHost(uint64 hostID)
{
CSteamID hostSteamID(hostID); CSteamID hostSteamID(hostID);
g_isClient = true; g_isClient = true;
g_hostSteamID = hostSteamID; g_hostSteamID = hostSteamID;
@@ -215,16 +273,20 @@ bool SteamNetworkingManager::joinHost(uint64 hostID) {
SteamNetworkingIdentity identity; SteamNetworkingIdentity identity;
identity.SetSteamID(hostSteamID); identity.SetSteamID(hostSteamID);
g_hConnection = m_pInterface->ConnectP2P(identity, g_currentVirtualPort, 2, g_connectionConfig); g_hConnection = m_pInterface->ConnectP2P(identity, g_currentVirtualPort, 2, g_connectionConfig);
if (g_hConnection != k_HSteamNetConnection_Invalid) { if (g_hConnection != k_HSteamNetConnection_Invalid)
{
std::cout << "Attempting to connect to host " << hostSteamID.ConvertToUint64() << " with virtual port " << g_currentVirtualPort << std::endl; std::cout << "Attempting to connect to host " << hostSteamID.ConvertToUint64() << " with virtual port " << g_currentVirtualPort << std::endl;
return true; return true;
} else { }
else
{
std::cerr << "Failed to initiate connection" << std::endl; std::cerr << "Failed to initiate connection" << std::endl;
return false; return false;
} }
} }
void SteamNetworkingManager::setMessageHandlerDependencies(boost::asio::io_context& io_context, std::map<HSteamNetConnection, std::shared_ptr<TCPClient>>& clientMap, std::mutex& clientMutex, std::unique_ptr<TCPServer>& server, int& localPort) { void SteamNetworkingManager::setMessageHandlerDependencies(boost::asio::io_context &io_context, std::map<HSteamNetConnection, std::shared_ptr<TCPClient>> &clientMap, std::mutex &clientMutex, std::unique_ptr<TCPServer> &server, int &localPort)
{
io_context_ = &io_context; io_context_ = &io_context;
clientMap_ = &clientMap; clientMap_ = &clientMap;
clientMutex_ = &clientMutex; clientMutex_ = &clientMutex;
@@ -233,39 +295,49 @@ void SteamNetworkingManager::setMessageHandlerDependencies(boost::asio::io_conte
messageHandler_ = new SteamMessageHandler(io_context, m_pInterface, connections, clientMap, clientMutex, connectionsMutex, server, g_isHost, localPort); messageHandler_ = new SteamMessageHandler(io_context, m_pInterface, connections, clientMap, clientMutex, connectionsMutex, server, g_isHost, localPort);
} }
void SteamNetworkingManager::startMessageHandler() { void SteamNetworkingManager::startMessageHandler()
if (messageHandler_) { {
if (messageHandler_)
{
messageHandler_->start(); messageHandler_->start();
} }
} }
void SteamNetworkingManager::stopMessageHandler() { void SteamNetworkingManager::stopMessageHandler()
if (messageHandler_) { {
if (messageHandler_)
{
messageHandler_->stop(); messageHandler_->stop();
} }
} }
void SteamNetworkingManager::update() { void SteamNetworkingManager::update()
{
std::lock_guard<std::mutex> lock(connectionsMutex); std::lock_guard<std::mutex> lock(connectionsMutex);
for (auto& pair : userMap) { for (auto &pair : userMap)
{
HSteamNetConnection conn = pair.first; HSteamNetConnection conn = pair.first;
UserInfo& userInfo = pair.second; UserInfo &userInfo = pair.second;
SteamNetConnectionInfo_t info; SteamNetConnectionInfo_t info;
SteamNetConnectionRealTimeStatus_t status; SteamNetConnectionRealTimeStatus_t status;
if (m_pInterface->GetConnectionInfo(conn, &info) && m_pInterface->GetConnectionRealTimeStatus(conn, &status, 0, nullptr)) { if (m_pInterface->GetConnectionInfo(conn, &info) && m_pInterface->GetConnectionRealTimeStatus(conn, &status, 0, nullptr))
{
userInfo.ping = status.m_nPing; userInfo.ping = status.m_nPing;
userInfo.isRelay = (info.m_idPOPRelay != 0); userInfo.isRelay = (info.m_idPOPRelay != 0);
} }
} }
} }
void SteamNetworkingManager::handleConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t *pInfo) { void SteamNetworkingManager::handleConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t *pInfo)
{
std::lock_guard<std::mutex> lock(connectionsMutex); std::lock_guard<std::mutex> lock(connectionsMutex);
std::cout << "Connection status changed: " << pInfo->m_info.m_eState << " for connection " << pInfo->m_hConn << std::endl; std::cout << "Connection status changed: " << pInfo->m_info.m_eState << " for connection " << pInfo->m_hConn << std::endl;
if (pInfo->m_info.m_eState == k_ESteamNetworkingConnectionState_ProblemDetectedLocally) { if (pInfo->m_info.m_eState == k_ESteamNetworkingConnectionState_ProblemDetectedLocally)
{
std::cout << "Connection failed: " << pInfo->m_info.m_szEndDebug << std::endl; std::cout << "Connection failed: " << pInfo->m_info.m_szEndDebug << std::endl;
} }
if (pInfo->m_eOldState == k_ESteamNetworkingConnectionState_None && pInfo->m_info.m_eState == k_ESteamNetworkingConnectionState_Connecting) { if (pInfo->m_eOldState == k_ESteamNetworkingConnectionState_None && pInfo->m_info.m_eState == k_ESteamNetworkingConnectionState_Connecting)
{
m_pInterface->AcceptConnection(pInfo->m_hConn); m_pInterface->AcceptConnection(pInfo->m_hConn);
connections.push_back(pInfo->m_hConn); connections.push_back(pInfo->m_hConn);
g_hConnection = pInfo->m_hConn; g_hConnection = pInfo->m_hConn;
@@ -274,7 +346,8 @@ void SteamNetworkingManager::handleConnectionStatusChanged(SteamNetConnectionSta
// Add user info // Add user info
SteamNetConnectionInfo_t info; SteamNetConnectionInfo_t info;
SteamNetConnectionRealTimeStatus_t status; SteamNetConnectionRealTimeStatus_t status;
if (m_pInterface->GetConnectionInfo(pInfo->m_hConn, &info) && m_pInterface->GetConnectionRealTimeStatus(pInfo->m_hConn, &status, 0, nullptr)) { if (m_pInterface->GetConnectionInfo(pInfo->m_hConn, &info) && m_pInterface->GetConnectionRealTimeStatus(pInfo->m_hConn, &status, 0, nullptr))
{
UserInfo userInfo; UserInfo userInfo;
userInfo.steamID = pInfo->m_info.m_identityRemote.GetSteamID(); userInfo.steamID = pInfo->m_info.m_identityRemote.GetSteamID();
userInfo.name = SteamFriends()->GetFriendPersonaName(userInfo.steamID); userInfo.name = SteamFriends()->GetFriendPersonaName(userInfo.steamID);
@@ -283,13 +356,16 @@ void SteamNetworkingManager::handleConnectionStatusChanged(SteamNetConnectionSta
userMap[pInfo->m_hConn] = userInfo; userMap[pInfo->m_hConn] = userInfo;
std::cout << "Incoming connection details: ping=" << status.m_nPing << "ms, relay=" << (info.m_idPOPRelay != 0 ? "yes" : "no") << std::endl; std::cout << "Incoming connection details: ping=" << status.m_nPing << "ms, relay=" << (info.m_idPOPRelay != 0 ? "yes" : "no") << std::endl;
} }
} else if (pInfo->m_eOldState == k_ESteamNetworkingConnectionState_Connecting && pInfo->m_info.m_eState == k_ESteamNetworkingConnectionState_Connected) { }
else if (pInfo->m_eOldState == k_ESteamNetworkingConnectionState_Connecting && pInfo->m_info.m_eState == k_ESteamNetworkingConnectionState_Connected)
{
g_isConnected = true; g_isConnected = true;
std::cout << "Connected to host" << std::endl; std::cout << "Connected to host" << std::endl;
// Add user info // Add user info
SteamNetConnectionInfo_t info; SteamNetConnectionInfo_t info;
SteamNetConnectionRealTimeStatus_t status; SteamNetConnectionRealTimeStatus_t status;
if (m_pInterface->GetConnectionInfo(pInfo->m_hConn, &info) && m_pInterface->GetConnectionRealTimeStatus(pInfo->m_hConn, &status, 0, nullptr)) { if (m_pInterface->GetConnectionInfo(pInfo->m_hConn, &info) && m_pInterface->GetConnectionRealTimeStatus(pInfo->m_hConn, &status, 0, nullptr))
{
UserInfo userInfo; UserInfo userInfo;
userInfo.steamID = pInfo->m_info.m_identityRemote.GetSteamID(); userInfo.steamID = pInfo->m_info.m_identityRemote.GetSteamID();
userInfo.name = SteamFriends()->GetFriendPersonaName(userInfo.steamID); userInfo.name = SteamFriends()->GetFriendPersonaName(userInfo.steamID);
@@ -298,38 +374,47 @@ void SteamNetworkingManager::handleConnectionStatusChanged(SteamNetConnectionSta
userMap[pInfo->m_hConn] = userInfo; userMap[pInfo->m_hConn] = userInfo;
std::cout << "Outgoing connection details: ping=" << status.m_nPing << "ms, relay=" << (info.m_idPOPRelay != 0 ? "yes" : "no") << std::endl; std::cout << "Outgoing connection details: ping=" << status.m_nPing << "ms, relay=" << (info.m_idPOPRelay != 0 ? "yes" : "no") << std::endl;
} }
} else if (pInfo->m_info.m_eState == k_ESteamNetworkingConnectionState_ClosedByPeer || pInfo->m_info.m_eState == k_ESteamNetworkingConnectionState_ProblemDetectedLocally) { }
else if (pInfo->m_info.m_eState == k_ESteamNetworkingConnectionState_ClosedByPeer || pInfo->m_info.m_eState == k_ESteamNetworkingConnectionState_ProblemDetectedLocally)
{
g_isConnected = false; g_isConnected = false;
g_hConnection = k_HSteamNetConnection_Invalid; g_hConnection = k_HSteamNetConnection_Invalid;
// Remove from connections // Remove from connections
auto it = std::find(connections.begin(), connections.end(), pInfo->m_hConn); auto it = std::find(connections.begin(), connections.end(), pInfo->m_hConn);
if (it != connections.end()) { if (it != connections.end())
{
connections.erase(it); connections.erase(it);
} }
userMap.erase(pInfo->m_hConn); userMap.erase(pInfo->m_hConn);
std::cout << "Connection closed" << std::endl; std::cout << "Connection closed" << std::endl;
// Retry if client // Retry if client
if (g_isClient && !g_isConnected && g_retryCount < MAX_RETRIES) { if (g_isClient && !g_isConnected && g_retryCount < MAX_RETRIES)
{
g_retryCount++; g_retryCount++;
g_currentVirtualPort++; g_currentVirtualPort++;
SteamNetworkingIdentity identity; SteamNetworkingIdentity identity;
identity.SetSteamID(g_hostSteamID); identity.SetSteamID(g_hostSteamID);
HSteamNetConnection newConn = m_pInterface->ConnectP2P(identity, g_currentVirtualPort, 2, g_connectionConfig); HSteamNetConnection newConn = m_pInterface->ConnectP2P(identity, g_currentVirtualPort, 2, g_connectionConfig);
if (newConn != k_HSteamNetConnection_Invalid) { if (newConn != k_HSteamNetConnection_Invalid)
{
g_hConnection = newConn; g_hConnection = newConn;
std::cout << "Retrying connection attempt " << g_retryCount << " with virtual port " << g_currentVirtualPort << std::endl; std::cout << "Retrying connection attempt " << g_retryCount << " with virtual port " << g_currentVirtualPort << std::endl;
} else { }
else
{
std::cerr << "Failed to initiate retry connection" << std::endl; std::cerr << "Failed to initiate retry connection" << std::endl;
} }
} }
} }
} }
SteamMatchmakingCallbacks::SteamMatchmakingCallbacks(SteamNetworkingManager* manager) : manager_(manager) {} SteamMatchmakingCallbacks::SteamMatchmakingCallbacks(SteamNetworkingManager *manager) : manager_(manager) {}
void SteamMatchmakingCallbacks::OnLobbyCreated(LobbyCreated_t *pCallback) { void SteamMatchmakingCallbacks::OnLobbyCreated(LobbyCreated_t *pCallback)
if (pCallback->m_eResult == k_EResultOK) { {
if (pCallback->m_eResult == k_EResultOK)
{
manager_->currentLobby = pCallback->m_ulSteamIDLobby; manager_->currentLobby = pCallback->m_ulSteamIDLobby;
std::cout << "Lobby created: " << manager_->currentLobby.ConvertToUint64() << std::endl; std::cout << "Lobby created: " << manager_->currentLobby.ConvertToUint64() << std::endl;
// Set Rich Presence with lobby ID // Set Rich Presence with lobby ID
@@ -338,38 +423,50 @@ void SteamMatchmakingCallbacks::OnLobbyCreated(LobbyCreated_t *pCallback) {
SteamFriends()->SetRichPresence("status", "主持游戏房间"); SteamFriends()->SetRichPresence("status", "主持游戏房间");
SteamFriends()->SetRichPresence("steam_display", "#StatusWithConnectFormat"); SteamFriends()->SetRichPresence("steam_display", "#StatusWithConnectFormat");
std::cout << "Set Rich Presence connect to: " << lobbyStr << std::endl; std::cout << "Set Rich Presence connect to: " << lobbyStr << std::endl;
} else { }
else
{
std::cerr << "Failed to create lobby" << std::endl; std::cerr << "Failed to create lobby" << std::endl;
} }
} }
void SteamMatchmakingCallbacks::OnLobbyListReceived(LobbyMatchList_t *pCallback) { void SteamMatchmakingCallbacks::OnLobbyListReceived(LobbyMatchList_t *pCallback)
{
manager_->lobbies.clear(); manager_->lobbies.clear();
for (uint32 i = 0; i < pCallback->m_nLobbiesMatching; ++i) { for (uint32 i = 0; i < pCallback->m_nLobbiesMatching; ++i)
{
CSteamID lobbyID = SteamMatchmaking()->GetLobbyByIndex(i); CSteamID lobbyID = SteamMatchmaking()->GetLobbyByIndex(i);
manager_->lobbies.push_back(lobbyID); manager_->lobbies.push_back(lobbyID);
} }
std::cout << "Received " << pCallback->m_nLobbiesMatching << " lobbies" << std::endl; std::cout << "Received " << pCallback->m_nLobbiesMatching << " lobbies" << std::endl;
} }
void SteamMatchmakingCallbacks::OnLobbyEntered(LobbyEnter_t *pCallback) { void SteamMatchmakingCallbacks::OnLobbyEntered(LobbyEnter_t *pCallback)
if (pCallback->m_EChatRoomEnterResponse == k_EChatRoomEnterResponseSuccess) { {
if (pCallback->m_EChatRoomEnterResponse == k_EChatRoomEnterResponseSuccess)
{
manager_->currentLobby = pCallback->m_ulSteamIDLobby; manager_->currentLobby = pCallback->m_ulSteamIDLobby;
std::cout << "Entered lobby: " << pCallback->m_ulSteamIDLobby << std::endl; std::cout << "Entered lobby: " << pCallback->m_ulSteamIDLobby << std::endl;
// Only join host if not the host // Only join host if not the host
if (!manager_->isHost()) { if (!manager_->isHost())
{
CSteamID hostID = SteamMatchmaking()->GetLobbyOwner(pCallback->m_ulSteamIDLobby); CSteamID hostID = SteamMatchmaking()->GetLobbyOwner(pCallback->m_ulSteamIDLobby);
if (manager_->joinHost(hostID.ConvertToUint64())) { if (manager_->joinHost(hostID.ConvertToUint64()))
{
// Start TCP Server if dependencies are set // Start TCP Server if dependencies are set
if (manager_->server_ && !(*manager_->server_)) { if (manager_->server_ && !(*manager_->server_))
{
*manager_->server_ = std::make_unique<TCPServer>(8888, manager_); *manager_->server_ = std::make_unique<TCPServer>(8888, manager_);
if (!(*manager_->server_)->start()) { if (!(*manager_->server_)->start())
{
std::cerr << "Failed to start TCP server" << std::endl; std::cerr << "Failed to start TCP server" << std::endl;
} }
} }
} }
} }
} else { }
else
{
std::cerr << "Failed to enter lobby" << std::endl; std::cerr << "Failed to enter lobby" << std::endl;
} }
} }

View File

@@ -119,7 +119,7 @@ private:
std::mutex connectionsMutex; std::mutex connectionsMutex;
// Connection config // Connection config
SteamNetworkingConfigValue_t g_connectionConfig[2]; SteamNetworkingConfigValue_t g_connectionConfig[3];
int g_retryCount; int g_retryCount;
const int MAX_RETRIES = 3; const int MAX_RETRIES = 3;
int g_currentVirtualPort; int g_currentVirtualPort;