#include "inetworkserver.h" #include "tier1/utlmutex.h" #include "tier1/utlvector.h" class CLocalNetworkServer; static CLocalNetworkServer *s_pLocalServers[128]; class CLocalNetworkServer: public INetworkBase { public: CLocalNetworkServer( uint16_t uPort ); virtual ~CLocalNetworkServer() override; virtual void NetThink() override; virtual uint32_t BHasUpdates() override; virtual NetPacket_t RecievePacket() override; virtual NetPacket_t PeekPacket() override; virtual void SendPacket( NetPacket_t stPacket ) override; virtual uint64_t GetSteamID() override; virtual const char *GetIP() override; virtual uint16_t GetPort() override; CUtlLock m_lock; CUtlVector m_packets; CUtlVector m_clientPackets; CUtlVector m_freedPackets; const uint16_t m_uPort; }; CLocalNetworkServer::CLocalNetworkServer( uint16_t uPort ) : m_uPort(uPort) { s_pLocalServers[uPort] = this; } CLocalNetworkServer::~CLocalNetworkServer() { s_pLocalServers[m_uPort] = NULL; } void CLocalNetworkServer::NetThink() { m_lock.Lock(); for ( auto p: m_freedPackets) { V_free(p); } m_freedPackets = {}; m_lock.Unlock(); } uint32_t CLocalNetworkServer::BHasUpdates() { return m_clientPackets.GetSize(); } NetPacket_t CLocalNetworkServer::RecievePacket() { m_lock.Lock(); if (!BHasUpdates()) return {}; NetPacket_t p = m_clientPackets[0]; m_clientPackets.RemoveHead(1); m_freedPackets.AppendTail(p.pData); m_lock.Unlock(); return p; } NetPacket_t CLocalNetworkServer::PeekPacket() { m_lock.Lock(); if (!BHasUpdates()) return {}; NetPacket_t p = m_clientPackets[0]; m_lock.Unlock(); return p; } void CLocalNetworkServer::SendPacket( NetPacket_t stPacket ) { NetPacket_t stSavedPacked; stSavedPacked.uSize = stPacket.uSize; stSavedPacked.pData = V_malloc(stPacket.uSize); V_memcpy(stSavedPacked.pData, stPacket.pData, stPacket.uSize); m_lock.Lock(); m_packets.AppendTail(stSavedPacked); m_lock.Unlock(); } uint64_t CLocalNetworkServer::GetSteamID() { return 0; } const char *CLocalNetworkServer::GetIP() { return NULL; } uint16_t CLocalNetworkServer::GetPort() { return m_uPort; } class CLocalNetworkClient: public INetworkBase { public: CLocalNetworkClient( uint16_t uPort ); virtual ~CLocalNetworkClient() override; virtual void NetThink() override; virtual uint32_t BHasUpdates() override; virtual NetPacket_t RecievePacket() override; virtual NetPacket_t PeekPacket() override; virtual void SendPacket( NetPacket_t stPacket ) override; virtual uint64_t GetSteamID() override; virtual const char *GetIP() override; virtual uint16_t GetPort() override; CLocalNetworkServer *m_pServer; }; CLocalNetworkClient::CLocalNetworkClient( uint16_t uPort ) { m_pServer = s_pLocalServers[uPort]; } CLocalNetworkClient::~CLocalNetworkClient() { } void CLocalNetworkClient::NetThink() { } uint32_t CLocalNetworkClient::BHasUpdates() { return m_pServer->m_packets.GetSize(); } NetPacket_t CLocalNetworkClient::RecievePacket() { m_pServer->m_lock.Lock(); if (!BHasUpdates()) return {}; NetPacket_t p = m_pServer->m_packets[0]; m_pServer->m_packets.RemoveHead(1); m_pServer->m_freedPackets.AppendTail(p.pData); m_pServer->m_lock.Unlock(); return p; } NetPacket_t CLocalNetworkClient::PeekPacket() { m_pServer->m_lock.Lock(); if (!BHasUpdates()) return {}; NetPacket_t p = m_pServer->m_packets[0]; m_pServer->m_lock.Unlock(); return p; } void CLocalNetworkClient::SendPacket( NetPacket_t stPacket ) { NetPacket_t stSavedPacked; stSavedPacked.uSize = stPacket.uSize; stSavedPacked.pData = V_malloc(stPacket.uSize); V_memcpy(stSavedPacked.pData, stPacket.pData, stPacket.uSize); m_pServer->m_lock.Lock(); m_pServer->m_clientPackets.AppendTail(stSavedPacked); m_pServer->m_lock.Unlock(); } uint64_t CLocalNetworkClient::GetSteamID() { return 0; } const char *CLocalNetworkClient::GetIP() { return NULL; } uint16_t CLocalNetworkClient::GetPort() { return m_pServer->m_uPort; } INetworkBase *LaunchLocalBridge( uint16_t uPort ) { INetworkBase *pBase = new CLocalNetworkServer(uPort); return pBase; } INetworkBase *ConnectByLocalBridge( uint16_t uPort ) { if (s_pLocalServers[uPort] == 0) { return NULL; } return new CLocalNetworkClient(uPort); }