Skip to content

Commit 9e9e40e

Browse files
committed
(GNS) Added GNS and basic implementation.
1 parent 4772044 commit 9e9e40e

File tree

12 files changed

+908
-2
lines changed

12 files changed

+908
-2
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,6 @@
5555
[submodule "libs/tracy"]
5656
path = libs/tracy
5757
url = https://github.com/SpaRcle-Studio/tracy
58+
[submodule "libs/GameNetworkingSockets"]
59+
path = libs/GameNetworkingSockets
60+
url = https://github.com/SpaRcle-Studio/GameNetworkingSockets.git

CMakeLists.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ option(SR_COMMON_JSON "" OFF)
3636
option(SR_COMMON_MYHTML "" OFF)
3737
option(SR_COMMON_LITEHTML "" OFF)
3838
option(SR_COMMON_ASIO "" OFF)
39+
option(SR_COMMON_GNS "" OFF)
3940

4041
option(SR_COMMON_DLL_EXPORTS "" ON)
4142
option(SR_COMMON_GIT_METADATA "" ON)
@@ -201,6 +202,26 @@ if (SR_COMMON_ASIO)
201202
target_include_directories(asio INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/libs/asio/asio/include)
202203
endif()
203204

205+
if (SR_COMMON_GNS)
206+
set(BUILD_SHARED_LIB OFF CACHE INTERNAL "" FORCE)
207+
set(BUILD_STATIC_LIB ON CACHE INTERNAL "" FORCE)
208+
set(BUILD_EXAMPLES OFF CACHE INTERNAL "" FORCE)
209+
set(BUILD_TESTS OFF CACHE INTERNAL "" FORCE)
210+
set(BUILD_TOOLS OFF CACHE INTERNAL "" FORCE)
211+
set(ENABLE_ICE OFF CACHE INTERNAL "" FORCE)
212+
set(USE_STEAMWEBRTC OFF CACHE INTERNAL "" FORCE)
213+
set(LTO OFF CACHE INTERNAL "" FORCE)
214+
215+
if (WIN32)
216+
set(USE_CRYPTO "BCrypt" CACHE STRING "" FORCE)
217+
else()
218+
set(USE_CRYPTO "OpenSSL" CACHE STRING "" FORCE)
219+
endif()
220+
221+
add_subdirectory(libs/GameNetworkingSockets)
222+
SR_UTILS_INCLUDE_DIRECTORIES_APPEND(${CMAKE_CURRENT_SOURCE_DIR}/libs/GameNetworkingSockets/include)
223+
endif()
224+
204225
if (SR_EFSW_USE)
205226
set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "" FORCE)
206227
add_subdirectory(libs/efsw)

cmake/SRCommonLinking.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,9 @@ endif()
6161
if (SR_COMMON_ASIO)
6262
target_link_libraries(Utils asio)
6363
target_compile_definitions(Utils PUBLIC SR_COMMON_ASIO)
64+
endif()
65+
66+
if (SR_COMMON_GNS)
67+
target_link_libraries(Utils GameNetworkingSockets_s)
68+
target_compile_definitions(Utils PUBLIC SR_COMMON_GNS)
6469
endif()

inc/Utils/Network/Context.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ namespace SR_NETWORK_NS {
1515

1616
SR_ENUM_NS_CLASS_T(NetworkLib, uint8_t,
1717
Unknown,
18-
Asio
18+
Asio,
19+
GNS
1920
)
2021

2122
SR_ENUM_NS_CLASS_T(SocketType, uint8_t,
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//
2+
// Created by innerviewer on 2026-03-17.
3+
//
4+
5+
#ifndef SR_UTILS_NETWORK_GNS_ACCEPTOR_H
6+
#define SR_UTILS_NETWORK_GNS_ACCEPTOR_H
7+
8+
#include <Utils/Network/Acceptor.h>
9+
10+
#include <steam/steamnetworkingsockets.h>
11+
12+
namespace SR_NETWORK_NS {
13+
class GNSContext;
14+
15+
class GNSAcceptor : public Acceptor {
16+
using Super = Acceptor;
17+
friend class GNSContext;
18+
private:
19+
GNSAcceptor(Context::Ptr pContext, std::string address, uint16_t port);
20+
21+
public:
22+
~GNSAcceptor() override;
23+
24+
public:
25+
void Close() override;
26+
27+
SR_NODISCARD std::string GetLocalAddress() const override;
28+
SR_NODISCARD std::string GetRemoteAddress() const override;
29+
30+
SR_NODISCARD uint16_t GetLocalPort() const override;
31+
SR_NODISCARD uint16_t GetRemotePort() const override;
32+
33+
SR_NODISCARD HSteamListenSocket GetListenSocket() const { return m_hListenSocket; }
34+
35+
/// Called by GNSContext when a new connection arrives on this listen socket.
36+
void OnIncomingConnection(HSteamNetConnection hConn);
37+
38+
private:
39+
bool Init() override;
40+
bool StartInternal(bool async) override;
41+
42+
private:
43+
HSteamListenSocket m_hListenSocket = k_HSteamListenSocket_Invalid;
44+
};
45+
}
46+
47+
#endif //SR_UTILS_NETWORK_GNS_ACCEPTOR_H

inc/Utils/Network/GNS/GNSContext.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//
2+
// Created by innerviewer on 2026-03-17.
3+
//
4+
5+
#ifndef SR_UTILS_NETWORK_GNS_CONTEXT_H
6+
#define SR_UTILS_NETWORK_GNS_CONTEXT_H
7+
8+
#include <Utils/Network/Context.h>
9+
10+
#include <steam/steamnetworkingsockets.h>
11+
#include <steam/isteamnetworkingutils.h>
12+
13+
namespace SR_NETWORK_NS {
14+
class GNSAcceptor;
15+
class GNSSocket;
16+
17+
class GNSContext : public Context {
18+
using Super = Context;
19+
public:
20+
GNSContext() = default;
21+
~GNSContext() override;
22+
23+
public:
24+
ISteamNetworkingSockets* GetInterface() const { return m_pInterface; }
25+
26+
bool Run() override;
27+
bool Poll() override;
28+
void Stop() override;
29+
30+
SR_NODISCARD SR_HTYPES_NS::SharedPtr<Socket> CreateSocket(SocketType type) override;
31+
SR_NODISCARD SR_HTYPES_NS::SharedPtr<Pinger> CreatePinger() override;
32+
SR_NODISCARD SR_HTYPES_NS::SharedPtr<Acceptor> CreateAcceptor(SocketType type, const std::string& address, uint16_t port) override;
33+
34+
void RegisterAcceptor(HSteamListenSocket hListenSocket, GNSAcceptor* pAcceptor);
35+
void UnregisterAcceptor(HSteamListenSocket hListenSocket);
36+
37+
void RegisterSocket(HSteamNetConnection hConn, GNSSocket* pSocket);
38+
void UnregisterSocket(HSteamNetConnection hConn);
39+
40+
static void OnConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t* pInfo);
41+
42+
private:
43+
void HandleConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t* pInfo);
44+
static void GNSDebugOutput(ESteamNetworkingSocketsDebugOutputType eType, const char* pszMsg);
45+
46+
private:
47+
ISteamNetworkingSockets* m_pInterface = nullptr;
48+
49+
std::map<HSteamListenSocket, GNSAcceptor*> m_acceptorMap;
50+
std::map<HSteamNetConnection, GNSSocket*> m_socketMap;
51+
52+
static GNSContext* s_pCallbackInstance;
53+
};
54+
}
55+
56+
#endif //SR_UTILS_NETWORK_GNS_CONTEXT_H

inc/Utils/Network/GNS/GNSSocket.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//
2+
// Created by innerviewer on 2026-03-17.
3+
//
4+
5+
#ifndef SR_UTILS_NETWORK_GNS_SOCKET_H
6+
#define SR_UTILS_NETWORK_GNS_SOCKET_H
7+
8+
#include <Utils/Network/Socket.h>
9+
10+
#include <steam/steamnetworkingsockets.h>
11+
12+
namespace SR_NETWORK_NS {
13+
class GNSContext;
14+
15+
class GNSSocket : public Socket {
16+
using Super = Socket;
17+
friend class GNSContext;
18+
friend class GNSAcceptor;
19+
public:
20+
enum class SendMode : uint8_t {
21+
Reliable,
22+
Unreliable,
23+
NoNagle,
24+
UnreliableNoNagle
25+
};
26+
27+
private:
28+
explicit GNSSocket(Context::Ptr pContext);
29+
30+
public:
31+
~GNSSocket() override;
32+
33+
public:
34+
bool Connect(const std::string& address, uint16_t port) override;
35+
bool Send(const void* data, size_t size) override;
36+
bool SendTo(const void* data, uint64_t size, const std::string& address, uint16_t port) override;
37+
bool Close() override;
38+
39+
uint64_t Receive(void* data, size_t size) override;
40+
uint64_t AsyncReceive(void* data, std::function<void(uint64_t bytesReceived)> callback) override;
41+
42+
SR_NODISCARD bool IsOpen() const override;
43+
44+
SR_NODISCARD std::string GetLocalAddress() const override;
45+
SR_NODISCARD std::string GetRemoteAddress() const override;
46+
47+
SR_NODISCARD uint16_t GetLocalPort() const override;
48+
SR_NODISCARD uint16_t GetRemotePort() const override;
49+
50+
void SetConnection(HSteamNetConnection hConn);
51+
void SetSendMode(SendMode mode) { m_sendMode = mode; }
52+
53+
SR_NODISCARD HSteamNetConnection GetConnection() const { return m_hConn; }
54+
SR_NODISCARD SendMode GetSendMode() const { return m_sendMode; }
55+
56+
/// Send with an explicit reliability mode.
57+
bool SendWithFlags(const void* data, size_t size, int32_t sendFlags);
58+
59+
void OnConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t* pInfo);
60+
61+
protected:
62+
bool ReceiveAsyncInternal() override;
63+
64+
private:
65+
SR_NODISCARD int32_t GetSendFlags() const;
66+
67+
private:
68+
HSteamNetConnection m_hConn = k_HSteamNetConnection_Invalid;
69+
SendMode m_sendMode = SendMode::Reliable;
70+
};
71+
}
72+
73+
#endif //SR_UTILS_NETWORK_GNS_SOCKET_H

libs/GameNetworkingSockets

Submodule GameNetworkingSockets added at 517fff0

src/Utils/Network/Context.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,19 @@
1212
#include <Utils/Network/Asio/AsioContext.h>
1313
#endif
1414

15+
#ifdef SR_COMMON_GNS
16+
#include <Utils/Network/GNS/GNSContext.h>
17+
#endif
18+
1519
namespace SR_NETWORK_NS {
1620
Context::Context()
1721
: Super(this, SR_UTILS_NS::SharedPtrPolicy::Automatic)
1822
{ }
1923

2024
SR_HTYPES_NS::SharedPtr<Context> Context::Create() {
21-
#ifdef SR_COMMON_ASIO
25+
#ifdef SR_COMMON_GNS
26+
return GNSContext::MakeShared<GNSContext, Context>();
27+
#elif defined(SR_COMMON_ASIO)
2228
return AsioContext::MakeShared<AsioContext, Context>();
2329
#else
2430
SR_ERROR("Context::Create() : no implementation for this platform!");

0 commit comments

Comments
 (0)