重构Steam网络管理,整合房间管理功能,添加多路复用支持,优化TCP服务器和消息处理
This commit is contained in:
80
multiplex/multiplex_manager.cpp
Normal file
80
multiplex/multiplex_manager.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
#include "multiplex_manager.h"
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
MultiplexManager::MultiplexManager(ISteamNetworkingSockets* steamInterface, HSteamNetConnection steamConn)
|
||||
: steamInterface_(steamInterface), steamConn_(steamConn), nextId_(1) {}
|
||||
|
||||
MultiplexManager::~MultiplexManager() {
|
||||
// Close all sockets
|
||||
std::lock_guard<std::mutex> lock(mapMutex_);
|
||||
for (auto& pair : clientMap_) {
|
||||
pair.second->close();
|
||||
}
|
||||
clientMap_.clear();
|
||||
}
|
||||
|
||||
uint32_t MultiplexManager::addClient(std::shared_ptr<tcp::socket> socket) {
|
||||
std::lock_guard<std::mutex> lock(mapMutex_);
|
||||
uint32_t id = nextId_++;
|
||||
clientMap_[id] = socket;
|
||||
return id;
|
||||
}
|
||||
|
||||
void MultiplexManager::removeClient(uint32_t id) {
|
||||
std::lock_guard<std::mutex> lock(mapMutex_);
|
||||
auto it = clientMap_.find(id);
|
||||
if (it != clientMap_.end()) {
|
||||
it->second->close();
|
||||
clientMap_.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<tcp::socket> MultiplexManager::getClient(uint32_t id) {
|
||||
std::lock_guard<std::mutex> 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<char> packet(packetSize);
|
||||
uint32_t* pId = reinterpret_cast<uint32_t*>(&packet[0]);
|
||||
uint32_t* pType = reinterpret_cast<uint32_t*>(&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<const uint32_t*>(data);
|
||||
uint32_t type = *reinterpret_cast<const uint32_t*>(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;
|
||||
}
|
||||
}
|
||||
33
multiplex/multiplex_manager.h
Normal file
33
multiplex/multiplex_manager.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <boost/asio.hpp>
|
||||
#include <steam_api.h>
|
||||
#include <isteamnetworkingsockets.h>
|
||||
#include <steamnetworkingtypes.h>
|
||||
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
class MultiplexManager {
|
||||
public:
|
||||
MultiplexManager(ISteamNetworkingSockets* steamInterface, HSteamNetConnection steamConn);
|
||||
~MultiplexManager();
|
||||
|
||||
uint32_t addClient(std::shared_ptr<tcp::socket> socket);
|
||||
void removeClient(uint32_t id);
|
||||
std::shared_ptr<tcp::socket> 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<uint32_t, std::shared_ptr<tcp::socket>> clientMap_;
|
||||
std::mutex mapMutex_;
|
||||
uint32_t nextId_;
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<TCPClient>("localhost", localPort_);
|
||||
if (client->connect()) {
|
||||
client->setReceiveCallback([conn, this](const char* data, size_t size) {
|
||||
std::lock_guard<std::mutex> lock(clientMutex_);
|
||||
m_pInterface_->SendMessageToConnection(conn, data, size, k_nSteamNetworkingSend_Reliable, nullptr);
|
||||
});
|
||||
client->setDisconnectCallback([conn, this]() {
|
||||
std::lock_guard<std::mutex> 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();
|
||||
}
|
||||
|
||||
@@ -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<CSteamID>& SteamNetworkingManager::getLobbies() const
|
||||
{
|
||||
static std::vector<CSteamID> 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);
|
||||
|
||||
@@ -9,9 +9,7 @@
|
||||
#include <isteamnetworkingsockets.h>
|
||||
#include <isteamnetworkingutils.h>
|
||||
#include <steamnetworkingtypes.h>
|
||||
#include <isteammatchmaking.h>
|
||||
#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<CSteamID>& 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<std::pair<CSteamID, std::string>>& getFriendsList() const { return friendsList; }
|
||||
const std::map<HSteamNetConnection, UserInfo>& getUserMap() const { return userMap; }
|
||||
const std::vector<HSteamNetConnection>& getConnections() const { return connections; }
|
||||
HSteamNetConnection getConnection() const { return g_hConnection; }
|
||||
ISteamNetworkingSockets* getInterface() const { return m_pInterface; }
|
||||
|
||||
// For SteamRoomManager access
|
||||
std::unique_ptr<TCPServer>*& getServer() { return server_; }
|
||||
int*& getLocalPort() { return localPort_; }
|
||||
boost::asio::io_context*& getIOContext() { return io_context_; }
|
||||
std::map<HSteamNetConnection, std::shared_ptr<TCPClient>>*& 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<HSteamNetConnection, std::shared_ptr<TCPClient>>& clientMap, std::mutex& clientMutex, std::unique_ptr<TCPServer>& 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<std::pair<CSteamID, std::string>> friendsList;
|
||||
|
||||
// Room manager
|
||||
SteamRoomManager* roomManager_;
|
||||
|
||||
// Message handler dependencies
|
||||
boost::asio::io_context* io_context_;
|
||||
std::map<HSteamNetConnection, std::shared_ptr<TCPClient>>* clientMap_;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
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<TCPServer>(8888, manager_);
|
||||
if (!(*manager_->server_)->start())
|
||||
*manager_->getServer() = std::make_unique<TCPServer>(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<TCPServer>(8888, manager_);
|
||||
if (!(*manager_->server_)->start())
|
||||
*manager_->getServer() = std::make_unique<TCPServer>(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;
|
||||
}
|
||||
@@ -5,28 +5,31 @@
|
||||
#include <mutex>
|
||||
|
||||
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
|
||||
|
||||
13
steam/steam_utils.cpp
Normal file
13
steam/steam_utils.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "steam_utils.h"
|
||||
#include <iostream>
|
||||
|
||||
std::vector<std::pair<CSteamID, std::string>> SteamUtils::getFriendsList() {
|
||||
std::vector<std::pair<CSteamID, std::string>> 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;
|
||||
}
|
||||
9
steam/steam_utils.h
Normal file
9
steam/steam_utils.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <steam_api.h>
|
||||
|
||||
class SteamUtils {
|
||||
public:
|
||||
static std::vector<std::pair<CSteamID, std::string>> getFriendsList();
|
||||
};
|
||||
@@ -3,19 +3,20 @@
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
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<MultiplexManager>(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<tcp::socket> 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<std::mutex> 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<tcp::socket> socket) {
|
||||
void TCPServer::start_read(std::shared_ptr<tcp::socket> socket, uint32_t id) {
|
||||
auto buffer = std::make_shared<std::vector<char>>(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;
|
||||
std::cout << "Received " << bytes_transferred << " bytes from TCP client " << id << std::endl;
|
||||
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);
|
||||
multiplexManager_->sendTunnelPacket(id, buffer->data(), bytes_transferred, 0);
|
||||
} else {
|
||||
std::cout << "Not connected to Steam, skipping forward" << std::endl;
|
||||
}
|
||||
forwarding_ = false;
|
||||
}
|
||||
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<std::mutex> lock(clientsMutex_);
|
||||
clients_.erase(std::remove(clients_.begin(), clients_.end(), socket), clients_.end());
|
||||
// Reset to allow new connection
|
||||
hasAcceptedConnection_ = false;
|
||||
if (running_) {
|
||||
start_accept();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -6,9 +6,11 @@
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
#include <isteamnetworkingsockets.h>
|
||||
#include <isteamnetworkingutils.h>
|
||||
#include <steamnetworkingtypes.h>
|
||||
#include "../multiplex/multiplex_manager.h"
|
||||
|
||||
class SteamNetworkingManager;
|
||||
|
||||
@@ -25,10 +27,11 @@ public:
|
||||
void sendToAll(const std::string& message, std::shared_ptr<tcp::socket> excludeSocket = nullptr);
|
||||
void sendToAll(const char* data, size_t size, std::shared_ptr<tcp::socket> excludeSocket = nullptr);
|
||||
int getClientCount();
|
||||
MultiplexManager* getMultiplexManager() { return multiplexManager_.get(); }
|
||||
|
||||
private:
|
||||
void start_accept();
|
||||
void start_read(std::shared_ptr<tcp::socket> socket);
|
||||
void start_read(std::shared_ptr<tcp::socket> socket, uint32_t id);
|
||||
|
||||
int port_;
|
||||
bool running_;
|
||||
@@ -38,7 +41,6 @@ private:
|
||||
std::vector<std::shared_ptr<tcp::socket>> clients_;
|
||||
std::mutex clientsMutex_;
|
||||
std::thread serverThread_;
|
||||
bool hasAcceptedConnection_;
|
||||
SteamNetworkingManager* manager_;
|
||||
bool forwarding_;
|
||||
std::unique_ptr<MultiplexManager> multiplexManager_;
|
||||
};
|
||||
Reference in New Issue
Block a user