305 lines
11 KiB
C++
305 lines
11 KiB
C++
#include <GLFW/glfw3.h>
|
|
#include <imgui.h>
|
|
#include <imgui_impl_glfw.h>
|
|
#include <imgui_impl_opengl3.h>
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <thread>
|
|
#include <mutex>
|
|
#include <map>
|
|
#include <algorithm>
|
|
#include <cstring>
|
|
#include <boost/asio.hpp>
|
|
#include <memory>
|
|
#include "tcp_server.h"
|
|
#include "steam/steam_networking_manager.h"
|
|
#include "steam/steam_room_manager.h"
|
|
#include "steam/steam_utils.h"
|
|
|
|
using boost::asio::ip::tcp;
|
|
|
|
// New variables for multiple connections and TCP clients
|
|
std::vector<HSteamNetConnection> connections;
|
|
std::mutex connectionsMutex; // Add mutex for connections
|
|
int localPort = 0;
|
|
std::unique_ptr<TCPServer> server;
|
|
|
|
int main()
|
|
{
|
|
boost::asio::io_context io_context;
|
|
|
|
// Initialize Steam Networking Manager
|
|
SteamNetworkingManager steamManager;
|
|
if (!steamManager.initialize())
|
|
{
|
|
std::cerr << "Failed to initialize Steam Networking Manager" << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
// Initialize Steam Room Manager
|
|
SteamRoomManager roomManager(&steamManager);
|
|
|
|
// Initialize GLFW
|
|
if (!glfwInit())
|
|
{
|
|
std::cerr << "Failed to initialize GLFW" << std::endl;
|
|
steamManager.shutdown();
|
|
return -1;
|
|
}
|
|
|
|
// Create window
|
|
GLFWwindow *window = glfwCreateWindow(1280, 720, "在线游戏工具", nullptr, nullptr);
|
|
if (!window)
|
|
{
|
|
std::cerr << "Failed to create GLFW window" << std::endl;
|
|
glfwTerminate();
|
|
SteamAPI_Shutdown();
|
|
return -1;
|
|
}
|
|
glfwMakeContextCurrent(window);
|
|
glfwSwapInterval(1); // Enable vsync
|
|
|
|
// Initialize ImGui
|
|
IMGUI_CHECKVERSION();
|
|
ImGui::CreateContext();
|
|
ImGuiIO &io = ImGui::GetIO();
|
|
(void)io;
|
|
// Load Chinese font
|
|
io.Fonts->AddFontFromFileTTF("font.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesChineseSimplifiedCommon());
|
|
ImGui::StyleColorsDark();
|
|
|
|
// Initialize ImGui backends
|
|
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
|
ImGui_ImplOpenGL3_Init("#version 130");
|
|
|
|
// Set message handler dependencies
|
|
steamManager.setMessageHandlerDependencies(io_context, server, localPort);
|
|
steamManager.startMessageHandler();
|
|
|
|
// Steam Networking variables
|
|
bool isHost = false;
|
|
bool isClient = false;
|
|
char joinBuffer[256] = "";
|
|
char filterBuffer[256] = "";
|
|
|
|
// Lambda to render invite friends UI
|
|
auto renderInviteFriends = [&]()
|
|
{
|
|
ImGui::InputText("过滤朋友", filterBuffer, IM_ARRAYSIZE(filterBuffer));
|
|
ImGui::Text("朋友:");
|
|
for (const auto &friendPair : SteamUtils::getFriendsList())
|
|
{
|
|
std::string nameStr = friendPair.second;
|
|
std::string filterStr(filterBuffer);
|
|
// Convert to lowercase for case-insensitive search
|
|
std::transform(nameStr.begin(), nameStr.end(), nameStr.begin(), ::tolower);
|
|
std::transform(filterStr.begin(), filterStr.end(), filterStr.begin(), ::tolower);
|
|
if (filterStr.empty() || nameStr.find(filterStr) != std::string::npos)
|
|
{
|
|
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(roomManager.getCurrentLobby().ConvertToUint64());
|
|
// Safety check for SteamFriends
|
|
if (SteamFriends())
|
|
{
|
|
SteamFriends()->InviteUserToGame(friendPair.first, connectStr.c_str());
|
|
std::cout << "Sent invite to " << friendPair.second << " with connect string: " << connectStr << std::endl;
|
|
}
|
|
else
|
|
{
|
|
std::cerr << "SteamFriends() is null! Cannot send invite." << std::endl;
|
|
}
|
|
}
|
|
ImGui::PopID();
|
|
}
|
|
}
|
|
};
|
|
|
|
// Main loop
|
|
while (!glfwWindowShouldClose(window))
|
|
{
|
|
// Poll events
|
|
glfwPollEvents();
|
|
|
|
// Run Steam callbacks
|
|
SteamAPI_RunCallbacks();
|
|
|
|
// Update Steam networking info
|
|
steamManager.update();
|
|
|
|
// Start ImGui frame
|
|
ImGui_ImplOpenGL3_NewFrame();
|
|
ImGui_ImplGlfw_NewFrame();
|
|
ImGui::NewFrame();
|
|
|
|
// Create a window for online game tool
|
|
ImGui::Begin("在线游戏工具");
|
|
if (server)
|
|
{
|
|
ImGui::Text("TCP服务器监听端口8888");
|
|
ImGui::Text("已连接客户端: %d", server->getClientCount());
|
|
}
|
|
ImGui::Separator();
|
|
|
|
if (!steamManager.isHost() && !steamManager.isConnected())
|
|
{
|
|
if (ImGui::Button("主持游戏房间"))
|
|
{
|
|
roomManager.startHosting();
|
|
}
|
|
ImGui::InputText("房间ID", joinBuffer, IM_ARRAYSIZE(joinBuffer));
|
|
if (ImGui::Button("加入游戏房间"))
|
|
{
|
|
uint64 hostID = std::stoull(joinBuffer);
|
|
if (steamManager.joinHost(hostID))
|
|
{
|
|
// Start TCP Server
|
|
server = std::make_unique<TCPServer>(8888, &steamManager);
|
|
if (!server->start())
|
|
{
|
|
std::cerr << "Failed to start TCP server" << std::endl;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (steamManager.isHost())
|
|
{
|
|
ImGui::Text("正在主持游戏房间。邀请朋友!");
|
|
ImGui::Separator();
|
|
ImGui::InputInt("本地端口", &localPort);
|
|
ImGui::Separator();
|
|
renderInviteFriends();
|
|
ImGui::Separator();
|
|
if (ImGui::Button("断开连接"))
|
|
{
|
|
roomManager.leaveLobby();
|
|
steamManager.disconnect();
|
|
if (server)
|
|
{
|
|
server->stop();
|
|
server.reset();
|
|
}
|
|
}
|
|
}
|
|
if (steamManager.isConnected() && !steamManager.isHost())
|
|
{
|
|
ImGui::Text("已连接到游戏房间。邀请朋友!");
|
|
ImGui::Separator();
|
|
if (ImGui::Button("断开连接"))
|
|
{
|
|
roomManager.leaveLobby();
|
|
steamManager.disconnect();
|
|
if (server)
|
|
{
|
|
server->stop();
|
|
server.reset();
|
|
}
|
|
}
|
|
ImGui::Separator();
|
|
renderInviteFriends();
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
// Room status window - only show when hosting or connected
|
|
if ((steamManager.isHost() || steamManager.isConnected()) && roomManager.getCurrentLobby().IsValid())
|
|
{
|
|
ImGui::Begin("房间状态");
|
|
ImGui::Text("用户列表:");
|
|
if (ImGui::BeginTable("UserTable", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg))
|
|
{
|
|
ImGui::TableSetupColumn("名称");
|
|
ImGui::TableSetupColumn("延迟 (ms)");
|
|
ImGui::TableSetupColumn("连接类型");
|
|
ImGui::TableHeadersRow();
|
|
{
|
|
std::vector<CSteamID> members = roomManager.getLobbyMembers();
|
|
CSteamID mySteamID = SteamUser()->GetSteamID();
|
|
for (const auto &memberID : members)
|
|
{
|
|
ImGui::TableNextRow();
|
|
ImGui::TableNextColumn();
|
|
const char *name = SteamFriends()->GetFriendPersonaName(memberID);
|
|
ImGui::Text("%s", name);
|
|
ImGui::TableNextColumn();
|
|
if (memberID == mySteamID)
|
|
{
|
|
ImGui::Text("-");
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("-");
|
|
}
|
|
else
|
|
{
|
|
int ping = 0;
|
|
std::string relayInfo = "N/A";
|
|
if (steamManager.isHost())
|
|
{
|
|
// Find connection for this member
|
|
std::lock_guard<std::mutex> lockConn(connectionsMutex);
|
|
for (const auto &conn : steamManager.getConnections())
|
|
{
|
|
SteamNetConnectionInfo_t info;
|
|
if (steamManager.getInterface()->GetConnectionInfo(conn, &info))
|
|
{
|
|
if (info.m_identityRemote.GetSteamID() == memberID)
|
|
{
|
|
ping = steamManager.getConnectionPing(conn);
|
|
relayInfo = steamManager.getConnectionRelayInfo(conn);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Client shows ping to host
|
|
ping = steamManager.getHostPing();
|
|
if (steamManager.getConnection() != k_HSteamNetConnection_Invalid)
|
|
{
|
|
relayInfo = steamManager.getConnectionRelayInfo(steamManager.getConnection());
|
|
}
|
|
}
|
|
ImGui::Text("%d", ping);
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%s", relayInfo.c_str());
|
|
}
|
|
}
|
|
}
|
|
ImGui::EndTable();
|
|
}
|
|
ImGui::End();
|
|
}
|
|
|
|
// Rendering
|
|
ImGui::Render();
|
|
int display_w, display_h;
|
|
glfwGetFramebufferSize(window, &display_w, &display_h);
|
|
glViewport(0, 0, display_w, display_h);
|
|
glClearColor(0.45f, 0.55f, 0.60f, 1.00f);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
|
|
|
// Swap buffers
|
|
glfwSwapBuffers(window);
|
|
}
|
|
|
|
// Stop message handler
|
|
steamManager.stopMessageHandler();
|
|
|
|
// Cleanup
|
|
if (server)
|
|
{
|
|
server->stop();
|
|
}
|
|
ImGui_ImplOpenGL3_Shutdown();
|
|
ImGui_ImplGlfw_Shutdown();
|
|
ImGui::DestroyContext();
|
|
glfwDestroyWindow(window);
|
|
glfwTerminate();
|
|
steamManager.shutdown();
|
|
|
|
return 0;
|
|
} |