From f661b1d3693aa5721433d72b03e8385949e35171 Mon Sep 17 00:00:00 2001 From: Ayndpa Date: Wed, 19 Nov 2025 16:49:36 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84Steam=E7=BD=91=E7=BB=9C?= =?UTF-8?q?=E7=AE=A1=E7=90=86=EF=BC=8C=E6=95=B4=E5=90=88=E6=88=BF=E9=97=B4?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=9A=E8=B7=AF=E5=A4=8D=E7=94=A8=E6=94=AF=E6=8C=81=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96TCP=E6=9C=8D=E5=8A=A1=E5=99=A8=E5=92=8C?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- multiplex/multiplex_manager.cpp | 80 ++++++++++++++++++++++++++++++ multiplex/multiplex_manager.h | 33 ++++++++++++ online_game_tool.cpp | 19 ++++--- steam/steam_message_handler.cpp | 32 ++---------- steam/steam_networking_manager.cpp | 78 +---------------------------- steam/steam_networking_manager.h | 34 ++++--------- steam/steam_room_manager.cpp | 50 +++++++++---------- steam/steam_room_manager.h | 7 ++- steam/steam_utils.cpp | 13 +++++ steam/steam_utils.h | 9 ++++ tcp/tcp_server.cpp | 46 ++++++++--------- tcp/tcp_server.h | 8 +-- 12 files changed, 217 insertions(+), 192 deletions(-) create mode 100644 multiplex/multiplex_manager.cpp create mode 100644 multiplex/multiplex_manager.h create mode 100644 steam/steam_utils.cpp create mode 100644 steam/steam_utils.h diff --git a/multiplex/multiplex_manager.cpp b/multiplex/multiplex_manager.cpp new file mode 100644 index 0000000..8492ef1 --- /dev/null +++ b/multiplex/multiplex_manager.cpp @@ -0,0 +1,80 @@ +#include "multiplex_manager.h" +#include +#include + +MultiplexManager::MultiplexManager(ISteamNetworkingSockets* steamInterface, HSteamNetConnection steamConn) + : steamInterface_(steamInterface), steamConn_(steamConn), nextId_(1) {} + +MultiplexManager::~MultiplexManager() { + // Close all sockets + std::lock_guard lock(mapMutex_); + for (auto& pair : clientMap_) { + pair.second->close(); + } + clientMap_.clear(); +} + +uint32_t MultiplexManager::addClient(std::shared_ptr socket) { + std::lock_guard lock(mapMutex_); + uint32_t id = nextId_++; + clientMap_[id] = socket; + return id; +} + +void MultiplexManager::removeClient(uint32_t id) { + std::lock_guard lock(mapMutex_); + auto it = clientMap_.find(id); + if (it != clientMap_.end()) { + it->second->close(); + clientMap_.erase(it); + } +} + +std::shared_ptr MultiplexManager::getClient(uint32_t id) { + std::lock_guard lock(mapMutex_); + auto it = clientMap_.find(id); + if (it != clientMap_.end()) { + return it->second; + } + return nullptr; +} + +void MultiplexManager::sendTunnelPacket(uint32_t id, const char* data, size_t len, int type) { + // Packet format: uint32_t id, uint32_t type, then data if type==0 + size_t packetSize = sizeof(uint32_t) * 2 + (type == 0 ? len : 0); + std::vector packet(packetSize); + uint32_t* pId = reinterpret_cast(&packet[0]); + uint32_t* pType = reinterpret_cast(&packet[sizeof(uint32_t)]); + *pId = id; + *pType = type; + if (type == 0 && data) { + std::memcpy(&packet[sizeof(uint32_t) * 2], data, len); + } + steamInterface_->SendMessageToConnection(steamConn_, packet.data(), packet.size(), k_nSteamNetworkingSend_Reliable, nullptr); +} + +void MultiplexManager::handleTunnelPacket(const char* data, size_t len) { + if (len < sizeof(uint32_t) * 2) { + std::cerr << "Invalid tunnel packet size" << std::endl; + return; + } + uint32_t id = *reinterpret_cast(data); + uint32_t type = *reinterpret_cast(data + sizeof(uint32_t)); + if (type == 0) { + // Data packet + size_t dataLen = len - sizeof(uint32_t) * 2; + const char* packetData = data + sizeof(uint32_t) * 2; + auto socket = getClient(id); + if (socket) { + boost::asio::async_write(*socket, boost::asio::buffer(packetData, dataLen), [](const boost::system::error_code&, std::size_t) {}); + } else { + std::cerr << "No client found for id " << id << std::endl; + } + } else if (type == 1) { + // Disconnect packet + removeClient(id); + std::cout << "Client " << id << " disconnected" << std::endl; + } else { + std::cerr << "Unknown packet type " << type << std::endl; + } +} \ No newline at end of file diff --git a/multiplex/multiplex_manager.h b/multiplex/multiplex_manager.h new file mode 100644 index 0000000..d30889e --- /dev/null +++ b/multiplex/multiplex_manager.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +using boost::asio::ip::tcp; + +class MultiplexManager { +public: + MultiplexManager(ISteamNetworkingSockets* steamInterface, HSteamNetConnection steamConn); + ~MultiplexManager(); + + uint32_t addClient(std::shared_ptr socket); + void removeClient(uint32_t id); + std::shared_ptr getClient(uint32_t id); + + void sendTunnelPacket(uint32_t id, const char* data, size_t len, int type); + + void handleTunnelPacket(const char* data, size_t len); + +private: + ISteamNetworkingSockets* steamInterface_; + HSteamNetConnection steamConn_; + std::unordered_map> clientMap_; + std::mutex mapMutex_; + uint32_t nextId_; +}; \ No newline at end of file diff --git a/online_game_tool.cpp b/online_game_tool.cpp index e7bb94d..b81c682 100644 --- a/online_game_tool.cpp +++ b/online_game_tool.cpp @@ -15,6 +15,8 @@ #include "tcp_server.h" #include "tcp/tcp_client.h" #include "steam/steam_networking_manager.h" +#include "steam/steam_room_manager.h" +#include "steam/steam_utils.h" using boost::asio::ip::tcp; @@ -36,6 +38,9 @@ int main() { return 1; } + // Initialize Steam Room Manager + SteamRoomManager roomManager(&steamManager); + // Initialize GLFW if (!glfwInit()) { std::cerr << "Failed to initialize GLFW" << std::endl; @@ -81,7 +86,7 @@ int main() { auto renderInviteFriends = [&]() { ImGui::InputText("过滤朋友", filterBuffer, IM_ARRAYSIZE(filterBuffer)); ImGui::Text("朋友:"); - for (const auto& friendPair : steamManager.getFriendsList()) { + for (const auto& friendPair : SteamUtils::getFriendsList()) { std::string nameStr = friendPair.second; std::string filterStr(filterBuffer); // Convert to lowercase for case-insensitive search @@ -91,7 +96,7 @@ int main() { ImGui::PushID(friendPair.first.ConvertToUint64()); if (ImGui::Button(("邀请 " + friendPair.second).c_str())) { // Send invite via Steam with lobby ID as connect string - std::string connectStr = std::to_string(steamManager.getCurrentLobby().ConvertToUint64()); + std::string connectStr = std::to_string(roomManager.getCurrentLobby().ConvertToUint64()); // Safety check for SteamFriends if (SteamFriends()) { SteamFriends()->InviteUserToGame(friendPair.first, connectStr.c_str()); @@ -131,10 +136,10 @@ int main() { if (!steamManager.isHost() && !steamManager.isConnected()) { if (ImGui::Button("主持游戏房间")) { - steamManager.startHosting(); + roomManager.startHosting(); } if (ImGui::Button("搜索游戏房间")) { - steamManager.searchLobbies(); + roomManager.searchLobbies(); } ImGui::InputText("主机Steam ID", joinBuffer, IM_ARRAYSIZE(joinBuffer)); if (ImGui::Button("加入游戏房间")) { @@ -148,12 +153,12 @@ int main() { } } // Display available lobbies - if (!steamManager.getLobbies().empty()) { + if (!roomManager.getLobbies().empty()) { ImGui::Text("可用房间:"); - for (const auto& lobbyID : steamManager.getLobbies()) { + for (const auto& lobbyID : roomManager.getLobbies()) { std::string lobbyName = "房间 " + std::to_string(lobbyID.ConvertToUint64()); if (ImGui::Button(lobbyName.c_str())) { - steamManager.joinLobby(lobbyID); + roomManager.joinLobby(lobbyID); } } } diff --git a/steam/steam_message_handler.cpp b/steam/steam_message_handler.cpp index 89a58d5..10dfbe7 100644 --- a/steam/steam_message_handler.cpp +++ b/steam/steam_message_handler.cpp @@ -57,35 +57,9 @@ void SteamMessageHandler::pollMessages() { ISteamNetworkingMessage* pIncomingMsg = pIncomingMsgs[i]; const char* data = (const char*)pIncomingMsg->m_pData; size_t size = pIncomingMsg->m_cbSize; - // Normal forwarding - if (server_) { - server_->sendToAll((const char*)pIncomingMsg->m_pData, pIncomingMsg->m_cbSize); - } - // Lazy connect: Create TCP Client on first message if not already connected - if (clientMap_.find(conn) == clientMap_.end() && g_isHost_ && localPort_ > 0) { - auto client = std::make_shared("localhost", localPort_); - if (client->connect()) { - client->setReceiveCallback([conn, this](const char* data, size_t size) { - std::lock_guard lock(clientMutex_); - m_pInterface_->SendMessageToConnection(conn, data, size, k_nSteamNetworkingSend_Reliable, nullptr); - }); - client->setDisconnectCallback([conn, this]() { - std::lock_guard lock(clientMutex_); - if (clientMap_.count(conn)) { - clientMap_[conn]->disconnect(); - clientMap_.erase(conn); - std::cout << "TCP client disconnected, removed from map" << std::endl; - } - }); - clientMap_[conn] = client; - std::cout << "Created TCP Client for connection on first message" << std::endl; - } else { - std::cerr << "Failed to connect TCP Client for connection" << std::endl; - } - } - // Send to corresponding TCP client if exists (for host) - if (clientMap_.count(conn)) { - clientMap_[conn]->send((const char*)pIncomingMsg->m_pData, pIncomingMsg->m_cbSize); + // Handle tunnel packets with multiplexing + if (server_ && server_->getMultiplexManager()) { + server_->getMultiplexManager()->handleTunnelPacket(data, size); } pIncomingMsg->Release(); } diff --git a/steam/steam_networking_manager.cpp b/steam/steam_networking_manager.cpp index 8588990..9032a34 100644 --- a/steam/steam_networking_manager.cpp +++ b/steam/steam_networking_manager.cpp @@ -16,8 +16,7 @@ void SteamNetworkingManager::OnSteamNetConnectionStatusChanged(SteamNetConnectio SteamNetworkingManager::SteamNetworkingManager() : m_pInterface(nullptr), hListenSock(k_HSteamListenSocket_Invalid), g_isHost(false), g_isClient(false), g_isConnected(false), g_hConnection(k_HSteamNetConnection_Invalid), - io_context_(nullptr), clientMap_(nullptr), clientMutex_(nullptr), server_(nullptr), localPort_(nullptr), messageHandler_(nullptr), - roomManager_(nullptr) + io_context_(nullptr), clientMap_(nullptr), clientMutex_(nullptr), server_(nullptr), localPort_(nullptr), messageHandler_(nullptr) { std::cout << "Initialized SteamNetworkingManager" << std::endl; } @@ -26,7 +25,6 @@ SteamNetworkingManager::~SteamNetworkingManager() { stopMessageHandler(); delete messageHandler_; - delete roomManager_; shutdown(); } @@ -85,36 +83,19 @@ bool SteamNetworkingManager::initialize() &allowWithoutAuth); // Create callbacks after Steam API init - roomManager_ = new SteamRoomManager(this); - SteamNetworkingUtils()->InitRelayNetworkAccess(); SteamNetworkingUtils()->SetGlobalCallback_SteamNetConnectionStatusChanged(OnSteamNetConnectionStatusChanged); m_pInterface = SteamNetworkingSockets(); - // Clear Rich Presence on startup - SteamFriends()->ClearRichPresence(); - std::cout << "Cleared Rich Presence on startup" << std::endl; - // Check if callbacks are registered std::cout << "Steam API initialized" << std::endl; - // Get friends list - int friendCount = SteamFriends()->GetFriendCount(k_EFriendFlagAll); - for (int i = 0; i < friendCount; ++i) - { - CSteamID friendID = SteamFriends()->GetFriendByIndex(i, k_EFriendFlagAll); - const char *name = SteamFriends()->GetFriendPersonaName(friendID); - friendsList.push_back({friendID, name}); - } - return true; } void SteamNetworkingManager::shutdown() { - if (roomManager_) - roomManager_->leaveLobby(); if (g_hConnection != k_HSteamNetConnection_Invalid) { m_pInterface->CloseConnection(g_hConnection, 0, nullptr, false); @@ -123,66 +104,9 @@ void SteamNetworkingManager::shutdown() { m_pInterface->CloseListenSocket(hListenSock); } - // Clear Rich Presence on shutdown - SteamFriends()->ClearRichPresence(); SteamAPI_Shutdown(); } -bool SteamNetworkingManager::createLobby() -{ - if (roomManager_) - return roomManager_->createLobby(); - return false; -} - -void SteamNetworkingManager::leaveLobby() -{ - if (roomManager_) - roomManager_->leaveLobby(); -} - -bool SteamNetworkingManager::searchLobbies() -{ - if (roomManager_) - return roomManager_->searchLobbies(); - return false; -} - -bool SteamNetworkingManager::joinLobby(CSteamID lobbyID) -{ - if (roomManager_) - return roomManager_->joinLobby(lobbyID); - return false; -} - -const std::vector& SteamNetworkingManager::getLobbies() const -{ - static std::vector empty; - if (roomManager_) - return roomManager_->getLobbies(); - return empty; -} - -CSteamID SteamNetworkingManager::getCurrentLobby() const -{ - if (roomManager_) - return roomManager_->getCurrentLobby(); - return k_steamIDNil; -} - -bool SteamNetworkingManager::startHosting() -{ - if (roomManager_) - return roomManager_->startHosting(); - return false; -} - -void SteamNetworkingManager::stopHosting() -{ - if (roomManager_) - roomManager_->stopHosting(); -} - bool SteamNetworkingManager::joinHost(uint64 hostID) { CSteamID hostSteamID(hostID); diff --git a/steam/steam_networking_manager.h b/steam/steam_networking_manager.h index 50acacc..0c1f9f4 100644 --- a/steam/steam_networking_manager.h +++ b/steam/steam_networking_manager.h @@ -9,9 +9,7 @@ #include #include #include -#include #include "steam_message_handler.h" -#include "steam_room_manager.h" // Forward declarations class TCPClient; @@ -35,18 +33,6 @@ public: bool initialize(); void shutdown(); - // Hosting - bool startHosting(); - void stopHosting(); - - // Lobby - bool createLobby(); - void leaveLobby(); - bool searchLobbies(); - bool joinLobby(CSteamID lobbyID); - const std::vector& getLobbies() const; - CSteamID getCurrentLobby() const; - // Joining bool joinHost(uint64 hostID); void disconnect(); @@ -55,12 +41,21 @@ public: bool isHost() const { return g_isHost; } bool isClient() const { return g_isClient; } bool isConnected() const { return g_isConnected; } - const std::vector>& getFriendsList() const { return friendsList; } const std::map& getUserMap() const { return userMap; } const std::vector& getConnections() const { return connections; } HSteamNetConnection getConnection() const { return g_hConnection; } ISteamNetworkingSockets* getInterface() const { return m_pInterface; } + // For SteamRoomManager access + std::unique_ptr*& getServer() { return server_; } + int*& getLocalPort() { return localPort_; } + boost::asio::io_context*& getIOContext() { return io_context_; } + std::map>*& getClientMap() { return clientMap_; } + std::mutex*& getClientMutex() { return clientMutex_; } + HSteamListenSocket& getListenSock() { return hListenSock; } + ISteamNetworkingSockets* getInterface() { return m_pInterface; } + bool& getIsHost() { return g_isHost; } + void setMessageHandlerDependencies(boost::asio::io_context& io_context, std::map>& clientMap, std::mutex& clientMutex, std::unique_ptr& server, int& localPort); // Message handler @@ -74,9 +69,6 @@ public: void setHostSteamID(CSteamID id) { g_hostSteamID = id; } CSteamID getHostSteamID() const { return g_hostSteamID; } - friend class SteamFriendsCallbacks; - friend class SteamMatchmakingCallbacks; - private: // Steam API ISteamNetworkingSockets* m_pInterface; @@ -99,12 +91,6 @@ private: const int MAX_RETRIES = 3; int g_currentVirtualPort; - // Friends - std::vector> friendsList; - - // Room manager - SteamRoomManager* roomManager_; - // Message handler dependencies boost::asio::io_context* io_context_; std::map>* clientMap_; diff --git a/steam/steam_room_manager.cpp b/steam/steam_room_manager.cpp index 9e6810b..cfa00c2 100644 --- a/steam/steam_room_manager.cpp +++ b/steam/steam_room_manager.cpp @@ -3,7 +3,7 @@ #include #include -SteamFriendsCallbacks::SteamFriendsCallbacks(SteamNetworkingManager *manager) : manager_(manager) +SteamFriendsCallbacks::SteamFriendsCallbacks(SteamNetworkingManager *manager, SteamRoomManager *roomManager) : manager_(manager), roomManager_(roomManager) { std::cout << "SteamFriendsCallbacks constructor called" << std::endl; } @@ -30,10 +30,10 @@ void SteamFriendsCallbacks::OnGameRichPresenceJoinRequested(GameRichPresenceJoin { manager_->joinHost(id); // Start TCP Server if dependencies are set - if (manager_->server_ && !(*manager_->server_)) + if (manager_->getServer() && !(*manager_->getServer())) { - *manager_->server_ = std::make_unique(8888, manager_); - if (!(*manager_->server_)->start()) + *manager_->getServer() = std::make_unique(8888, manager_); + if (!(*manager_->getServer())->start()) { std::cerr << "Failed to start TCP server" << std::endl; } @@ -52,7 +52,7 @@ void SteamFriendsCallbacks::OnGameRichPresenceJoinRequested(GameRichPresenceJoin if (!manager_->isHost() && !manager_->isConnected()) { std::cout << "Joining lobby from invite: " << id << std::endl; - manager_->joinLobby(lobbySteamID); + roomManager_->joinLobby(lobbySteamID); } else { @@ -86,7 +86,7 @@ void SteamFriendsCallbacks::OnGameLobbyJoinRequested(GameLobbyJoinRequested_t *p if (!manager_->isHost() && !manager_->isConnected()) { std::cout << "Joining lobby from request: " << lobbyID.ConvertToUint64() << std::endl; - manager_->joinLobby(lobbyID); + roomManager_->joinLobby(lobbyID); } else { @@ -99,16 +99,16 @@ void SteamFriendsCallbacks::OnGameLobbyJoinRequested(GameLobbyJoinRequested_t *p } } -SteamMatchmakingCallbacks::SteamMatchmakingCallbacks(SteamNetworkingManager *manager) : manager_(manager) {} +SteamMatchmakingCallbacks::SteamMatchmakingCallbacks(SteamNetworkingManager *manager, SteamRoomManager *roomManager) : manager_(manager), roomManager_(roomManager) {} void SteamMatchmakingCallbacks::OnLobbyCreated(LobbyCreated_t *pCallback) { if (pCallback->m_eResult == k_EResultOK) { - manager_->roomManager_->setCurrentLobby(pCallback->m_ulSteamIDLobby); - std::cout << "Lobby created: " << manager_->roomManager_->getCurrentLobby().ConvertToUint64() << std::endl; + roomManager_->setCurrentLobby(pCallback->m_ulSteamIDLobby); + std::cout << "Lobby created: " << roomManager_->getCurrentLobby().ConvertToUint64() << std::endl; // Set Rich Presence with lobby ID - std::string lobbyStr = std::to_string(manager_->roomManager_->getCurrentLobby().ConvertToUint64()); + std::string lobbyStr = std::to_string(roomManager_->getCurrentLobby().ConvertToUint64()); SteamFriends()->SetRichPresence("connect", lobbyStr.c_str()); SteamFriends()->SetRichPresence("status", "主持游戏房间"); SteamFriends()->SetRichPresence("steam_display", "#StatusWithConnectFormat"); @@ -122,11 +122,11 @@ void SteamMatchmakingCallbacks::OnLobbyCreated(LobbyCreated_t *pCallback) void SteamMatchmakingCallbacks::OnLobbyListReceived(LobbyMatchList_t *pCallback) { - manager_->roomManager_->clearLobbies(); + roomManager_->clearLobbies(); for (uint32 i = 0; i < pCallback->m_nLobbiesMatching; ++i) { CSteamID lobbyID = SteamMatchmaking()->GetLobbyByIndex(i); - manager_->roomManager_->addLobby(lobbyID); + roomManager_->addLobby(lobbyID); } std::cout << "Received " << pCallback->m_nLobbiesMatching << " lobbies" << std::endl; } @@ -135,7 +135,7 @@ void SteamMatchmakingCallbacks::OnLobbyEntered(LobbyEnter_t *pCallback) { if (pCallback->m_EChatRoomEnterResponse == k_EChatRoomEnterResponseSuccess) { - manager_->roomManager_->setCurrentLobby(pCallback->m_ulSteamIDLobby); + roomManager_->setCurrentLobby(pCallback->m_ulSteamIDLobby); std::cout << "Entered lobby: " << pCallback->m_ulSteamIDLobby << std::endl; // Only join host if not the host if (!manager_->isHost()) @@ -144,10 +144,10 @@ void SteamMatchmakingCallbacks::OnLobbyEntered(LobbyEnter_t *pCallback) if (manager_->joinHost(hostID.ConvertToUint64())) { // Start TCP Server if dependencies are set - if (manager_->server_ && !(*manager_->server_)) + if (manager_->getServer() && !(*manager_->getServer())) { - *manager_->server_ = std::make_unique(8888, manager_); - if (!(*manager_->server_)->start()) + *manager_->getServer() = std::make_unique(8888, manager_); + if (!(*manager_->getServer())->start()) { std::cerr << "Failed to start TCP server" << std::endl; } @@ -165,8 +165,8 @@ SteamRoomManager::SteamRoomManager(SteamNetworkingManager *networkingManager) : networkingManager_(networkingManager), currentLobby(k_steamIDNil), steamFriendsCallbacks(nullptr), steamMatchmakingCallbacks(nullptr) { - steamFriendsCallbacks = new SteamFriendsCallbacks(networkingManager_); - steamMatchmakingCallbacks = new SteamMatchmakingCallbacks(networkingManager_); + steamFriendsCallbacks = new SteamFriendsCallbacks(networkingManager_, this); + steamMatchmakingCallbacks = new SteamMatchmakingCallbacks(networkingManager_, this); } SteamRoomManager::~SteamRoomManager() @@ -227,11 +227,11 @@ bool SteamRoomManager::startHosting() return false; } - networkingManager_->hListenSock = networkingManager_->m_pInterface->CreateListenSocketP2P(0, 0, nullptr); + networkingManager_->getListenSock() = networkingManager_->getInterface()->CreateListenSocketP2P(0, 0, nullptr); - if (networkingManager_->hListenSock != k_HSteamListenSocket_Invalid) + if (networkingManager_->getListenSock() != k_HSteamListenSocket_Invalid) { - networkingManager_->g_isHost = true; + networkingManager_->getIsHost() = true; std::cout << "Created listen socket for hosting game room" << std::endl; // Rich Presence is set in OnLobbyCreated callback return true; @@ -246,11 +246,11 @@ bool SteamRoomManager::startHosting() void SteamRoomManager::stopHosting() { - if (networkingManager_->hListenSock != k_HSteamListenSocket_Invalid) + if (networkingManager_->getListenSock() != k_HSteamListenSocket_Invalid) { - networkingManager_->m_pInterface->CloseListenSocket(networkingManager_->hListenSock); - networkingManager_->hListenSock = k_HSteamListenSocket_Invalid; + networkingManager_->getInterface()->CloseListenSocket(networkingManager_->getListenSock()); + networkingManager_->getListenSock() = k_HSteamListenSocket_Invalid; } leaveLobby(); - networkingManager_->g_isHost = false; + networkingManager_->getIsHost() = false; } \ No newline at end of file diff --git a/steam/steam_room_manager.h b/steam/steam_room_manager.h index a35a9fe..166698b 100644 --- a/steam/steam_room_manager.h +++ b/steam/steam_room_manager.h @@ -5,28 +5,31 @@ #include class SteamNetworkingManager; // Forward declaration +class SteamRoomManager; // Forward declaration for callbacks class SteamFriendsCallbacks { public: - SteamFriendsCallbacks(SteamNetworkingManager *manager); + SteamFriendsCallbacks(SteamNetworkingManager *manager, SteamRoomManager *roomManager); void OnGameRichPresenceJoinRequested(GameRichPresenceJoinRequested_t *pCallback); void OnGameLobbyJoinRequested(GameLobbyJoinRequested_t *pCallback); private: SteamNetworkingManager *manager_; + SteamRoomManager *roomManager_; }; class SteamMatchmakingCallbacks { public: - SteamMatchmakingCallbacks(SteamNetworkingManager *manager); + SteamMatchmakingCallbacks(SteamNetworkingManager *manager, SteamRoomManager *roomManager); void OnLobbyCreated(LobbyCreated_t *pCallback); void OnLobbyListReceived(LobbyMatchList_t *pCallback); void OnLobbyEntered(LobbyEnter_t *pCallback); private: SteamNetworkingManager *manager_; + SteamRoomManager *roomManager_; }; class SteamRoomManager diff --git a/steam/steam_utils.cpp b/steam/steam_utils.cpp new file mode 100644 index 0000000..62f9495 --- /dev/null +++ b/steam/steam_utils.cpp @@ -0,0 +1,13 @@ +#include "steam_utils.h" +#include + +std::vector> SteamUtils::getFriendsList() { + std::vector> friendsList; + int friendCount = SteamFriends()->GetFriendCount(k_EFriendFlagAll); + for (int i = 0; i < friendCount; ++i) { + CSteamID friendID = SteamFriends()->GetFriendByIndex(i, k_EFriendFlagAll); + const char* name = SteamFriends()->GetFriendPersonaName(friendID); + friendsList.push_back({friendID, name}); + } + return friendsList; +} diff --git a/steam/steam_utils.h b/steam/steam_utils.h new file mode 100644 index 0000000..ea2640d --- /dev/null +++ b/steam/steam_utils.h @@ -0,0 +1,9 @@ +#pragma once +#include +#include +#include + +class SteamUtils { +public: + static std::vector> getFriendsList(); +}; \ No newline at end of file diff --git a/tcp/tcp_server.cpp b/tcp/tcp_server.cpp index cf8e389..77b78ce 100644 --- a/tcp/tcp_server.cpp +++ b/tcp/tcp_server.cpp @@ -3,19 +3,20 @@ #include #include -TCPServer::TCPServer(int port, SteamNetworkingManager* manager) : port_(port), running_(false), acceptor_(io_context_), work_(boost::asio::make_work_guard(io_context_)), hasAcceptedConnection_(false), manager_(manager), forwarding_(false) {} +TCPServer::TCPServer(int port, SteamNetworkingManager* manager) : port_(port), running_(false), acceptor_(io_context_), work_(boost::asio::make_work_guard(io_context_)), manager_(manager) {} TCPServer::~TCPServer() { stop(); } bool TCPServer::start() { try { - hasAcceptedConnection_ = false; tcp::endpoint endpoint(tcp::v4(), port_); acceptor_.open(endpoint.protocol()); acceptor_.set_option(tcp::acceptor::reuse_address(true)); acceptor_.bind(endpoint); acceptor_.listen(); + multiplexManager_ = std::make_unique(manager_->getInterface(), manager_->getConnection()); + running_ = true; serverThread_ = std::thread([this]() { std::cout << "Server thread started" << std::endl; @@ -33,12 +34,12 @@ bool TCPServer::start() { void TCPServer::stop() { running_ = false; - hasAcceptedConnection_ = false; io_context_.stop(); if (serverThread_.joinable()) { serverThread_.join(); } acceptor_.close(); + multiplexManager_.reset(); } void TCPServer::sendToAll(const std::string& message, std::shared_ptr excludeSocket) { @@ -64,46 +65,41 @@ void TCPServer::start_accept() { acceptor_.async_accept(*socket, [this, socket](const boost::system::error_code& error) { if (!error) { std::cout << "New client connected" << std::endl; + uint32_t id = multiplexManager_->addClient(socket); { std::lock_guard lock(clientsMutex_); clients_.push_back(socket); } - hasAcceptedConnection_ = true; - start_read(socket); + start_read(socket, id); } - if (running_ && !hasAcceptedConnection_) { + if (running_) { start_accept(); } }); } -void TCPServer::start_read(std::shared_ptr socket) { +void TCPServer::start_read(std::shared_ptr socket, uint32_t id) { auto buffer = std::make_shared>(1024); - socket->async_read_some(boost::asio::buffer(*buffer), [this, socket, buffer](const boost::system::error_code& error, std::size_t bytes_transferred) { + socket->async_read_some(boost::asio::buffer(*buffer), [this, socket, buffer, id](const boost::system::error_code& error, std::size_t bytes_transferred) { if (!error) { - std::cout << "Received " << bytes_transferred << " bytes from TCP client" << std::endl; - if (!forwarding_) { - forwarding_ = true; - if (manager_->isConnected()) { - std::cout << "Forwarding TCP message to Steam connection" << std::endl; - manager_->getInterface()->SendMessageToConnection(manager_->getConnection(), buffer->data(), bytes_transferred, k_nSteamNetworkingSend_Reliable, nullptr); - } else { - std::cout << "Not connected to Steam, skipping forward" << std::endl; - } - forwarding_ = false; + std::cout << "Received " << bytes_transferred << " bytes from TCP client " << id << std::endl; + if (manager_->isConnected()) { + multiplexManager_->sendTunnelPacket(id, buffer->data(), bytes_transferred, 0); + } else { + std::cout << "Not connected to Steam, skipping forward" << std::endl; } sendToAll(buffer->data(), bytes_transferred, socket); - start_read(socket); + start_read(socket, id); } else { - std::cout << "TCP client disconnected or error: " << error.message() << std::endl; + std::cout << "TCP client " << id << " disconnected or error: " << error.message() << std::endl; + // Send disconnect packet + if (manager_->isConnected()) { + multiplexManager_->sendTunnelPacket(id, nullptr, 0, 1); + } // Remove client + multiplexManager_->removeClient(id); std::lock_guard lock(clientsMutex_); clients_.erase(std::remove(clients_.begin(), clients_.end(), socket), clients_.end()); - // Reset to allow new connection - hasAcceptedConnection_ = false; - if (running_) { - start_accept(); - } } }); } \ No newline at end of file diff --git a/tcp/tcp_server.h b/tcp/tcp_server.h index ef0e1bd..059e17f 100644 --- a/tcp/tcp_server.h +++ b/tcp/tcp_server.h @@ -6,9 +6,11 @@ #include #include #include +#include #include #include #include +#include "../multiplex/multiplex_manager.h" class SteamNetworkingManager; @@ -25,10 +27,11 @@ public: void sendToAll(const std::string& message, std::shared_ptr excludeSocket = nullptr); void sendToAll(const char* data, size_t size, std::shared_ptr excludeSocket = nullptr); int getClientCount(); + MultiplexManager* getMultiplexManager() { return multiplexManager_.get(); } private: void start_accept(); - void start_read(std::shared_ptr socket); + void start_read(std::shared_ptr socket, uint32_t id); int port_; bool running_; @@ -38,7 +41,6 @@ private: std::vector> clients_; std::mutex clientsMutex_; std::thread serverThread_; - bool hasAcceptedConnection_; SteamNetworkingManager* manager_; - bool forwarding_; + std::unique_ptr multiplexManager_; }; \ No newline at end of file