steam relay networking

This commit is contained in:
2026-03-01 23:06:28 +02:00
parent 03c560c2b7
commit 468d765aa1
16 changed files with 628 additions and 101 deletions

View File

@@ -1,4 +1,5 @@
#include "tier2/ifilesystem.h"
#include "tier0/commandline.h"
#include "materialsystem/imaterialsystem.h"
#include "enginebridge.h"
#include "worldrender.h"
@@ -9,6 +10,10 @@
#include "cglm/cglm.h"
#include "inetworkclient.h"
#include "netprotocol.h"
#ifdef STEAM
#include "steam/isteamgameserver.h"
#include "steam/steam_gameserver.h"
#endif
IFileSystem *filesystem;
IRenderContext *g_pRenderContext;
@@ -16,7 +21,9 @@ IGameWindow *g_pMainWindow;
static CEngineVars s_vars;
CEngineVars *g_pEngineVars = &s_vars;
EngineConsts_t *g_pEngineConstants;
INetworkBase *g_pServerBridge;
INetworkBase *g_pServerConnection;
class CFunnyGameBridge: public IEngineBridge
{
@@ -25,6 +32,11 @@ class CFunnyGameBridge: public IEngineBridge
virtual void Frame( float fDelta ) override;
virtual void Shutdown() override;
virtual void ConnectInterface( const char *psz, void *pInterface ) override;
void TryToConnectToServer();
bool m_bIsConnectedToSteamRelay;
bool m_bIsConnectedToServer;
};
IEngineBridge *EngineBridge()
@@ -35,16 +47,29 @@ IEngineBridge *EngineBridge()
EXPOSE_INTERFACE_FN(EngineBridge, IEngineBridge, ENGINE_BRIDGE_INTERFACE_VERSION)
void CFunnyGameBridge::Init()
{
g_pWorldRenderer->Init();
g_pServerBridge = g_pEngineConstants->ConnectLocalBridge(0);
#ifdef STEAM
if (g_pEngineConstants->m_bIsSteam)
{
SteamErrMsg err = { 0 };
m_bIsConnectedToSteamRelay = 0;
SteamNetworkingUtils()->InitRelayNetworkAccess();
}
#endif
PlayerJoined_t join = {
MESSAGE_PLAYER_JOINED,
"LocalPlayer"
};
g_pServerBridge->SendPacket({&join, sizeof(join)});
m_bIsConnectedToServer = false;
g_pServerBridge = g_pEngineConstants->ConnectLocalBridge(0);
if (g_pServerBridge)
{
PlayerJoined_t join = {
MESSAGE_PLAYER_JOINED,
"LocalPlayer"
};
g_pServerBridge->SendPacket({&join, sizeof(join)});
}
}
void CFunnyGameBridge::Tick( float fDelta )
@@ -70,55 +95,106 @@ searchIndex:
return (char*)pEntity+pCurrentMap->m_pFields[uCurrentIndex].m_uOffset;
}
void CFunnyGameBridge::TryToConnectToServer()
{
#ifdef STEAM
if (g_pEngineConstants->m_bIsSteam)
{
if (m_bIsConnectedToSteamRelay != 0 )
return;
if ( SteamNetworkingUtils()->GetRelayNetworkStatus(NULL) == k_ESteamNetworkingAvailability_Current)
{
m_bIsConnectedToSteamRelay = 1;
V_printf("%llu\n", SteamUser()->GetSteamID().ConvertToUint64());
if (CommandLine()->ParamValue("-steam-connect"))
{
char *pEnd = NULL;
uint64_t uValue = strtoull(CommandLine()->ParamValue("-steam-connect"), &pEnd, 10);
g_pServerConnection = g_pEngineConstants->ConnectSteamServer(uValue, FUNNY_SECURE_PORT);
if (g_pServerConnection)
{
m_bIsConnectedToServer = true;
}
return;
}
}
}
#endif
}
void CFunnyGameBridge::Frame( float fDelta )
{
g_pEngineVars->m_fTime += fDelta;
g_pEngineVars->m_fDeltaTime = fDelta;
g_pServerBridge->NetThink();
while ( g_pServerBridge->BHasUpdates() )
{
NetPacket_t packet = g_pServerBridge->PeekPacket();
// discard it
if (packet.uSize < sizeof (EMessageType))
continue;
PlayerPacket_t *pPacket = (PlayerPacket_t*)packet.pData;
C_BaseEntity *pEntity;
switch (pPacket->m_eType)
{
case MESSAGE_ENTITY_CLASS_SYNC:
pEntity = EntitySystem()->CreateByClassnameWithIndex(
(char*)pPacket->m_entityClass.m_szEntityName, pPacket->m_entityClass.m_uIndex
);
pEntity->Spawn();
g_pServerBridge->RecievePacket();
break;
case MESSAGE_ENTITY_DATA_SYNC:
pEntity = EntitySystem()->GetEntities()[pPacket->m_entityData.m_uIndex];
union {
void *pData;
char *pcCurrentData;
EntityDataSyncValue_t *pcSyncValue;
};
pData = pPacket;
pcCurrentData += sizeof(EntityDataSync_t);
for ( uint32_t u = 0; u < pPacket->m_entityData.m_uCount; u++ )
{
uint32_t uVariableSize = pcSyncValue->m_uVariableSize;
void *pValueData = (float*)ENT_GetNetMapData(
pEntity,
pEntity->GetRecvMap(),
pcSyncValue->m_uVariableIndex);
TryToConnectToServer();
pcCurrentData += sizeof(EntityDataSyncValue_t);
if (pValueData)
V_memcpy(pValueData, pcCurrentData, uVariableSize);
pcCurrentData += (uVariableSize+7) & ~7;
INetworkBase *pCurrentServer = g_pServerBridge;
pCurrentServer = g_pServerBridge;
if (m_bIsConnectedToServer)
if (g_pServerConnection->BIsActive())
pCurrentServer = g_pServerConnection;
if (pCurrentServer)
{
pCurrentServer->NetThink();
while ( pCurrentServer->BHasUpdates() )
{
NetPacket_t packet = pCurrentServer->PeekPacket();
// discard it
if (packet.uSize < sizeof (EMessageType))
continue;
PlayerPacket_t *pPacket = (PlayerPacket_t*)packet.pData;
C_BaseEntity *pEntity;
switch (pPacket->m_eType)
{
case MESSAGE_ENTITY_CLASS_SYNC:
pEntity = EntitySystem()->CreateByClassnameWithIndex(
(char*)pPacket->m_entityClass.m_szEntityName, pPacket->m_entityClass.m_uIndex
);
if (pEntity == NULL)
{
pCurrentServer->RecievePacket();
continue;
}
pEntity->Spawn();
pCurrentServer->RecievePacket();
break;
case MESSAGE_ENTITY_DATA_SYNC:
pEntity = EntitySystem()->GetEntities()[pPacket->m_entityData.m_uIndex];
if (pEntity == NULL)
{
pCurrentServer->RecievePacket();
continue;
}
union {
void *pData;
char *pcCurrentData;
EntityDataSyncValue_t *pcSyncValue;
};
pData = pPacket;
pcCurrentData += sizeof(EntityDataSync_t);
for ( uint32_t u = 0; u < pPacket->m_entityData.m_uCount; u++ )
{
uint32_t uVariableSize = pcSyncValue->m_uVariableSize;
void *pValueData = (float*)ENT_GetNetMapData(
pEntity,
pEntity->GetRecvMap(),
pcSyncValue->m_uVariableIndex);
pcCurrentData += sizeof(EntityDataSyncValue_t);
if (pValueData)
V_memcpy(pValueData, pcCurrentData, uVariableSize);
pcCurrentData += (uVariableSize+7) & ~7;
}
pCurrentServer->RecievePacket();
break;
default:
pCurrentServer->RecievePacket();
V_printf("worng packet\n");
continue;
}
g_pServerBridge->RecievePacket();
break;
default:
continue;
}
}