#include "tier2/ifilesystem.h" #include "tier0/commandline.h" #include "materialsystem/imaterialsystem.h" #include "enginebridge.h" #include "worldrender.h" #include "entitysystem.h" #include "baseentity.h" #include "game.h" #include "netprotocol.h" #include "userinput.h" #include "math.h" #ifdef STEAM #include "steam/isteamgameserver.h" #include "steam/steam_gameserver.h" #endif class CFunnyGameBridge: public IEngineBridge { virtual void Init() override; virtual void Tick( float fDelta ) override; 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; float m_fNetUpdateTimer; }; IEngineBridge *EngineBridge() { static CFunnyGameBridge s_bridge; return &s_bridge; } EXPOSE_INTERFACE_FN(EngineBridge, IEngineBridge, ENGINE_BRIDGE_INTERFACE_VERSION) void CFunnyGameBridge::Init() { Console()->AddCommand("exec game/core/default.cfg\n"); Console()->Execute(); g_pWorldRenderer->Init(); #ifdef STEAM if (g_pEngineConstants->m_bIsSteam) { SteamErrMsg err = { 0 }; m_bIsConnectedToSteamRelay = 0; SteamNetworkingUtils()->InitRelayNetworkAccess(); } #endif 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)}); } CreateInterfaceFn fnPhysicsFactory = Sys_GetFactory("RapierPhysics"); g_pPhysics = (IPhysics*)fnPhysicsFactory(PHYSICS_INTERFACE_VERSION, NULL); g_pPhysicsWorld = g_pPhysics->CreateWorld(); g_pHumanDeviceManager->SetDefaultInput(g_pMainInput); } void CFunnyGameBridge::Tick( float fDelta ) { } void CFunnyGameBridge::TryToConnectToServer() { #ifdef STEAM if (g_pEngineConstants->m_bIsSteam) { if (m_bIsConnectedToSteamRelay != 0 ) return; if ( SteamNetworkingUtils()->GetRelayNetworkStatus(NULL) != k_ESteamNetworkingAvailability_Current) return; m_bIsConnectedToSteamRelay = 1; if (!CommandLine()->ParamValue("-steam-connect")) return; V_printf("%llu\n", SteamUser()->GetSteamID().ConvertToUint64()); 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; C_BaseEntity **ppEntities = EntitySystem()->GetEntities(); for ( int i = 0; i < MAX_EDICTS; i++ ) { EntitySystem()->DestroyEntityByIndex(i); } } return; } #endif } void CFunnyGameBridge::Frame( float fDelta ) { g_pEngineVars->m_fTime += fDelta; g_pEngineVars->m_fDeltaTime = fDelta; TryToConnectToServer(); 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: case MESSAGE_ENTITY_DATA_SYNC: case k_EMessage_PlayerSetLocalEntity: EntitySystem()->NetRecvPacket(&packet); pCurrentServer->RecievePacket(); break; default: pCurrentServer->RecievePacket(); V_printf("worng packet\n"); continue; } } } EntitySystem()->Think(); float fTickRate = 1.0/60.0; m_fNetUpdateTimer += fDelta; if (m_fNetUpdateTimer >= fTickRate) m_fNetUpdateTimer = fTickRate; if (m_fNetUpdateTimer >= fTickRate) { m_fNetUpdateTimer-=fTickRate; m_fNetUpdateTimer = fmod(m_fNetUpdateTimer, fTickRate); if (pCurrentServer) EntitySystem()->NetSendThink(pCurrentServer); } g_pWorldRenderer->Frame(fDelta); } void CFunnyGameBridge::Shutdown() { } #define CONNECT_INTERFACE(szName, pGlobal) if (!V_strcmp(psz, szName)) { pGlobal = (typeof(pGlobal))pInterface; return; } void CFunnyGameBridge::ConnectInterface( const char *psz, void *pInterface ) { CONNECT_INTERFACE(FILESYSTEM_INTERFACE_VERSION, filesystem); CONNECT_INTERFACE(RENDER_CONTEXT_INTERFACE_VERSION, g_pRenderContext); CONNECT_INTERFACE(HUMAN_DEVICE_MANAGER_INTERFACE_VERSION, g_pHumanDeviceManager); CONNECT_INTERFACE("MainWindow", g_pMainWindow); CONNECT_INTERFACE("EngineConstants", g_pEngineConstants); }