improved server

This commit is contained in:
2025-07-14 14:59:41 +03:00
parent a9c28b8940
commit 3e27fb1bd4
20 changed files with 400 additions and 97 deletions

View File

@@ -17,6 +17,7 @@ CUtlVector<CUtlString> engine_CompiledFiles = {
"engine/input.cpp",
"engine/networking.cpp",
"engine/mesh.cpp",
/* entities */
"engine/baseentity.cpp",

View File

@@ -113,7 +113,6 @@ void C_BrushEntity::Think( float fDelta )
g_BrushVertices.AppendTail(vertexBuffer);
};
IGraphicsPipeline *g_BrushPipeline;
class CBrushRendering: public IRenderingPipelineStep
{
@@ -126,6 +125,7 @@ private:
DECLARE_MESH_RENDERING_STAGE(CBrushRendering, brush_rasterizer);
IGraphicsPipeline *g_BrushPipeline;
ITexture *bricks;
void CBrushRendering::Init()
{

View File

@@ -2,7 +2,6 @@
#include "fgui/fgui.h"
#include "input.h"
#include "networking.h"
#include "steam/isteamgameserver.h"
#include "tier0/network.h"
#include "tier0/platform.h"
#include "tier1/commandline.h"
@@ -17,6 +16,7 @@
#include "physics.h"
#include "signal.h"
#include "steam/steam_api.h"
#include "steam/isteamgameserver.h"
#include "steam/steam_gameserver.h"
#include "networking.h"
@@ -109,14 +109,6 @@ void IEngine::Init()
if (!ICommandLine::CheckParam("-dedicated"))
{
#ifdef STEAM_ENABLED
// Log in into steam
if (!SteamUser()->BLoggedOn())
{
SteamAPI_Shutdown();
Plat_FatalErrorFunc("User must be logged in to Steam");
}
#endif
// Run local client
g_localClient = new IIClient();
IIEngine::ConnectClient(g_localClient);
@@ -126,21 +118,7 @@ void IEngine::Init()
IInput::Init();
IInput::SetMouseMode(MOUSE_MODE_GAME);
IFGUI::Init();
} else {
#ifdef STEAM_ENABLED
// Run dedicated server with steam
SteamGameServer_Init(0, 27015, 27016, eServerModeAuthentication, "0.0.0.0");
SteamGameServer()->SetProduct("funnygame");
SteamGameServer()->SetGameDescription("not that funny but ok");
SteamGameServer()->SetModDir("funnygame");
SteamGameServer()->SetDedicatedServer(true);
SteamGameServer()->LogOnAnonymous();
int nMaxPlayers = atoi(ICommandLine::ParamValue("-maxplayers", "128"));
SteamGameServer()->SetMaxPlayerCount(nMaxPlayers);
SteamGameServer()->SetAdvertiseServerActive(true);
#endif
}
};
INetworking::Init();
@@ -164,8 +142,8 @@ void IEngine::Frame(float fDelta)
#ifdef STEAM_ENABLED
SteamAPI_RunCallbacks();
#endif
INetworking::Frame();
IServer::Think(fDelta);
INetworking::Frame();
if (!ICommandLine::CheckParam("-dedicated"))
{
IFGUI::Frame();

View File

@@ -73,7 +73,6 @@ void IGameModeManager::Frame( void )
//-----------------------------------------------------------------------------
void IGameModeManager::StartGameMode( const char *szName )
{
V_printf("starting game mode %s\n", szName);
if (pCurrentMode)
{
pCurrentMode->RoundEnd();
@@ -112,13 +111,10 @@ void IGameModeManager::RestartCurrentGameMode( void )
PacketGameMode_t mode = {};
mode.type = PACKET_TYPE_GAMEMODE_START;
V_memcpy(mode.szName,szCurrentModeName, min(szCurrentModeName.GetLenght(), 255));
V_printf("%u clients connected\n",g_clients.GetSize());
for (auto &client: g_clients)
{
INetworking::SendData(&mode, sizeof(mode), client, MESSAGE_MODE_RELIABLE);
V_printf("sending to %u\n",client->playerHandle);
};
V_printf("restarting game mode\n");
};
pCurrentMode->RoundEnd();
pCurrentMode->RoundBegin();

View File

@@ -168,7 +168,6 @@ void IInput_Bind( int argc, char **argv )
g_bindings[key].AppendTail(argv[i]);
g_bindings[key].AppendTail(" ");
}
V_printf("%s\n",g_bindings[key].GetString());
};
//-----------------------------------------------------------------------------

View File

@@ -0,0 +1,155 @@
#include "mesh.h"
#include "cglm/mat4.h"
#include "rendering.h"
CUtlVector<IMeshInstance*> g_meshes;
class CMeshInstance: public IMeshInstance
{
public:
virtual void SetPosition( vec3 position ) override;
virtual void SetRotationEuler( vec3 angle ) override;
virtual void SetRotationQuat( vec4 quaternion) override;
virtual void SetMatrix( mat4 matrix ) override;
virtual void SetScale( vec3 scale ) override;
virtual void Draw() override;
mat4 m_matrix;
vec3 m_position;
IVertexBuffer *m_pVertexBuffer;
IIndexBuffer *m_pIndexBuffer;
};
void CMeshInstance::SetPosition( vec3 position )
{
glm_vec3_copy(position, m_position);
}
void CMeshInstance::SetRotationEuler( vec3 angle )
{
}
void CMeshInstance::SetRotationQuat( vec4 quaternion)
{
}
void CMeshInstance::SetMatrix( mat4 matrix )
{
glm_mat4_copy(matrix, m_matrix);
}
void CMeshInstance::SetScale( vec3 scale )
{
}
void CMeshInstance::Draw()
{
g_meshes.AppendTail(this);
}
class CMesh: public IMesh
{
public:
virtual void SetVertexBuffer( IVertexBuffer *pBuffer ) override;
virtual void SetIndexBuffer( IIndexBuffer *pBuffer ) override;
virtual IMeshInstance *CreateInstance() override;
IVertexBuffer *m_pVertexBuffer = 0;
IIndexBuffer *m_pIndexBuffer = 0;
};
void CMesh::SetVertexBuffer( IVertexBuffer *pBuffer )
{
m_pVertexBuffer = pBuffer;
}
void CMesh::SetIndexBuffer( IIndexBuffer *pBuffer )
{
m_pIndexBuffer = pBuffer;
}
IMeshInstance *CMesh::CreateInstance()
{
CMeshInstance *pInstance = new CMeshInstance;
pInstance->m_pVertexBuffer = m_pVertexBuffer;
pInstance->m_pIndexBuffer = m_pIndexBuffer;
return pInstance;
};
IGraphicsPipeline *g_MeshPipeline;
class CMeshRendering: public IMeshRendering
{
virtual void Init() override;
virtual void Frame( float fDelta ) override;
virtual void Deinit() override;
};
void CMeshRendering::Init()
{
g_MeshPipeline = IRenderer::CreateGraphicsPipeline(
{
{"gfx/mesh_vert.shader", SHADER_TYPE_VERTEX},
{"gfx/mesh_frag.shader", SHADER_TYPE_FRAGMENT},
},
{
{SHADER_INPUT_TYPE_UNIFORM_BUFFER,0},
{SHADER_INPUT_TYPE_TEXTURES,1},
},
80,
20,
{{0,0,EVertexFormat::VERTEX_FORMAT_X32Y32Z32}, {12,1,EVertexFormat::VERTEX_FORMAT_X32Y32}},
{EImageFormat::IMAGE_FORMAT_R8G8B8A8},
true
);
}
void CMeshRendering::Frame( float fDelta )
{
IRenderer::ResetState();
IRenderer::SetDepthMode(DEPTH_MODE_LESS);
IRenderer::BindPipeline(g_MeshPipeline);
IRenderer::BindData(0, IRenderer::GetCameraMatrix(), 0);
IRenderer::PushBindings();
for (auto &v: g_meshes)
{
CMeshInstance *pMesh = (CMeshInstance*)v;
struct {
mat4 i;
uint32_t a = 0;
uint32_t b = 0;
uint32_t c = 0;
} constants;
glm_mat4_copy(pMesh->m_matrix,constants.i);
constants.i[3][0] = pMesh->m_position[0];
constants.i[3][1] = pMesh->m_position[1];
constants.i[3][2] = pMesh->m_position[2];
IRenderer::SetConstants(sizeof(constants), &constants);
IRenderer::Draw(pMesh->m_pVertexBuffer, pMesh->m_pIndexBuffer);
}
g_meshes = {};
}
void CMeshRendering::Deinit()
{
}
IMesh *IMeshRendering::CreateMesh()
{
CMesh *pMesh = new CMesh;
return pMesh;
};
DECLARE_MESH_RENDERING_STAGE(CMeshRendering, mesh_rendering)

View File

@@ -614,7 +614,7 @@ void IMetal::Frame()
{
mat4 perspective;
glm_mat4_inv(g_cameraView, g_cameraDataMap->viewprojection);
glm_perspective(glm_rad(90),(float)g_nWindowWidth/g_nWindowHeight, 0.01, 100, perspective);
glm_perspective(glm_rad(68),(float)g_nWindowWidth/g_nWindowHeight, 0.01, 10000, perspective);
glm_rotate(perspective, glm_rad(90), (vec4){1,0,0,0});
glm_scale(perspective, (vec4){1,-1,1,1});
glm_rotate(perspective, glm_rad(90), (vec4){0,0,1,0});

View File

@@ -5,6 +5,9 @@
#include "server.h"
#include "steam/isteamfriends.h"
#include "steam/isteamnetworking.h"
#include "steam/isteamnetworkingsockets.h"
#include "steam/steam_api_common.h"
#include "steam/steamnetworkingtypes.h"
#include "tier0/platform.h"
#include "tier0/lib.h"
#include "tier1/commandline.h"
@@ -12,7 +15,10 @@
#include "tier1/utlvector.h"
#include "baseplayer.h"
#include "steam/steam_api.h"
#include "steam/steam_gameserver.h"
#include "steam/steamnetworkingsockets.h"
#include "steam/isteamgameserver.h"
#include "steam/isteamnetworkingutils.h"
#ifndef STEAMNETWORKINGSOCKETS_OPENSOURCE
#include "steam/steam_api.h"
@@ -23,40 +29,88 @@ HSteamNetConnection net_server = 0;
HSteamListenSocket net_listenSocket = -1;
CUtlVector<IIClient*> net_clients;
class CNetworkingCallbacks
bool net_bIsServer = false;
static int net_nMaxPlayers = 0;
static uint64_t net_nLastSteamID = 90071992547409920;
class CClientNetworkingCallbacks
{
STEAM_CALLBACK(CClientNetworkingCallbacks, RelayNetworkStatusChanged, SteamRelayNetworkStatus_t);
};
void CClientNetworkingCallbacks::RelayNetworkStatusChanged( SteamRelayNetworkStatus_t *pCallback )
{
STEAM_CALLBACK(CNetworkingCallbacks, ClientConnectedCallback, SteamNetConnectionStatusChangedCallback_t);
};
void CNetworkingCallbacks::ClientConnectedCallback( SteamNetConnectionStatusChangedCallback_t *pCallback )
class CServerNetworkingCallbacks
{
STEAM_GAMESERVER_CALLBACK(CServerNetworkingCallbacks, ClientConnected, SteamNetConnectionStatusChangedCallback_t);
STEAM_GAMESERVER_CALLBACK(CServerNetworkingCallbacks, SteamNetAuthenticated, SteamNetAuthenticationStatus_t);
};
void CServerNetworkingCallbacks::ClientConnected( SteamNetConnectionStatusChangedCallback_t *pCallback )
{
INetworking::ClientConnectedCallback(pCallback);
};
void CServerNetworkingCallbacks::SteamNetAuthenticated( SteamNetAuthenticationStatus_t *pCallback )
{
if (net_nLastSteamID == SteamGameServer()->GetSteamID().ConvertToUint64())
return;
net_nLastSteamID = SteamGameServer()->GetSteamID().ConvertToUint64();
V_printf("-------------- SERVER INFO ----------------\n");
V_printf(" STEAMID64:\t%llu\n", net_nLastSteamID);
V_printf(" MAX PLAYERS:\t%i\n", net_nMaxPlayers);
V_printf("-------------- TIPS -----------------------\n");
V_printf(" players can join by using connect <STEAMID64>\n");
V_printf("-------------------------------------------\n");
};
bool net_bIsServer = false;
static CNetworkingCallbacks *pCallbacks;
static CServerNetworkingCallbacks *net_pServerCallbacks;
static CClientNetworkingCallbacks *net_pClientCallbacks;
void INetworking::Init()
{
Net_Init();
SteamDatagramErrMsg errMsg = {};
#ifdef STEAMNETWORKINGSOCKETS_OPENSOURCE
GameNetworkingSockets_Init(NULL, &errMsg)
#endif
SteamNetworkingUtils()->SetDebugOutputFunction(k_ESteamNetworkingSocketsDebugOutputType_Msg,
[](ESteamNetworkingSocketsDebugOutputType severity, const char *szMessage) {
V_printf("Steam: %s\n", szMessage);
});
if (ICommandLine::CheckParam("-steamdebug"))
{
SteamNetworkingUtils()->SetDebugOutputFunction(k_ESteamNetworkingSocketsDebugOutputType_Msg,
[](ESteamNetworkingSocketsDebugOutputType severity, const char *szMessage) {
V_printf("Steam: %s\n", szMessage);
});
}
if (ICommandLine::CheckParam("-dedicated"))
{
pCallbacks = new CNetworkingCallbacks;
SteamNetworkingIPAddr localAddress = {};
localAddress.Clear();
localAddress.SetIPv4(0x7F000001, 27015);
net_listenSocket = SteamNetworkingSockets()->CreateListenSocketIP(localAddress, 0, NULL);
net_pServerCallbacks = new CServerNetworkingCallbacks;
// Run dedicated server with steam
SteamGameServer_Init(0, 27015, 27016, eServerModeAuthentication, "0.0.0.0");
SteamGameServer()->SetProduct("funnygame");
SteamGameServer()->SetGameDescription("not that funny but ok");
SteamGameServer()->SetModDir("funnygame");
SteamGameServer()->SetDedicatedServer(true);
SteamGameServer()->LogOnAnonymous();
net_nMaxPlayers = atoi(ICommandLine::ParamValue("-maxplayers", "128"));
SteamGameServer()->SetMaxPlayerCount(net_nMaxPlayers);
SteamGameServer()->SetAdvertiseServerActive(true);
} else {
net_pClientCallbacks = new CClientNetworkingCallbacks;
}
SteamDatagramErrMsg errMsg = {};
SteamNetworkingUtils()->InitRelayNetworkAccess();
if (ICommandLine::CheckParam("-dedicated"))
{
net_listenSocket = SteamGameServerNetworkingSockets()->CreateListenSocketP2P(0, 0, NULL);
net_bIsServer = true;
}
}
@@ -65,7 +119,7 @@ void INetworking::Deinit()
if (net_listenSocket == -1)
return;
if (ICommandLine::CheckParam("-dedicated"))
SteamNetworkingSockets()->CloseListenSocket(net_listenSocket);
SteamGameServerNetworkingSockets()->CloseListenSocket(net_listenSocket);
else
SteamNetworkingSockets()->CloseConnection(net_listenSocket, 0, NULL, false);
}
@@ -86,17 +140,16 @@ bool INetworking::IsConnected()
}
void INetworking::Frame()
{
SteamNetworkingSockets()->RunCallbacks();
{
if (IsServer())
{
SteamGameServer_RunCallbacks();
for (auto &client: g_clients)
{
SteamNetworkingMessage_t *pMessages[64];
while (true)
{
int nMessages = SteamNetworkingSockets()->ReceiveMessagesOnConnection(client->playerHandle, pMessages, 64);
int nMessages = SteamGameServerNetworkingSockets()->ReceiveMessagesOnConnection(client->playerHandle, pMessages, 64);
if ( nMessages <= 0 )
break;
for ( int i = 0; i < nMessages; i++ )
@@ -106,6 +159,7 @@ void INetworking::Frame()
}
}
} else {
SteamNetworkingSockets()->RunCallbacks();
SteamNetworkingMessage_t *pMessages[64];
while (true)
{
@@ -140,7 +194,7 @@ void INetworking::SendData( void *pData, uint32_t nSize, IIClient *pClient, EMes
if (pClient == NULL)
r = SteamNetworkingSockets()->SendMessageToConnection(net_server, pData, nSize, nSendFlags, NULL);
else
r = SteamNetworkingSockets()->SendMessageToConnection(pClient->playerHandle, pData, nSize, nSendFlags, NULL);
r = SteamGameServerNetworkingSockets()->SendMessageToConnection(pClient->playerHandle, pData, nSize, nSendFlags, NULL);
}
void INetworking::SendDataEverybody( void *pData, uint32_t nSize, EMessageMode messageMode )
{
@@ -211,6 +265,7 @@ void INetworking::ProcessPacket( void *pData, uint32_t nSize, IIClient *pClient
.playerID = pPlayerPacket->playerID,
.playerHandle = pPlayerPacket->playerHandle,
};
V_printf("%i\n",g_clients.GetSize());
IIEngine::ConnectClient(pNewClient);
for (auto &client: g_clients)
@@ -258,9 +313,9 @@ uint32_t INetworking_IPv4ToUint(const char *szIP) {
void INetworking::JoinServer( const char *szIP )
{
g_clients = {};
if (net_connection)
{
g_clients = {};
SteamNetworkingSockets()->CloseConnection(net_connection, 0, NULL, false);
}
SteamNetworkingIPAddr localAddress = {};
@@ -270,6 +325,21 @@ void INetworking::JoinServer( const char *szIP )
net_server = net_connection;
}
void INetworking::JoinServer( uint64_t nSteamID )
{
g_clients = {};
if (net_connection)
{
SteamNetworkingSockets()->CloseConnection(net_connection, 0, NULL, false);
}
SteamNetworkingIdentity remoteIdentity = {};
remoteIdentity.Clear();
remoteIdentity.SetSteamID64(nSteamID);
net_connection = SteamNetworkingSockets()->ConnectP2P(remoteIdentity, 0, 0, 0);
net_server = net_connection;
}
void INetworking::ClientConnectedCallback( SteamNetConnectionStatusChangedCallback_t *pCallback )
{
IIClient *pClient = new IIClient;
@@ -353,4 +423,20 @@ void INetworking_Connect( int argc, char **argv )
INetworking::JoinServer(argv[1]);
};
ConCommand ConnectCmd("connect", INetworking_Connect);
void INetworking_ConnectFriend( int argc, char **argv )
{
if (ICommandLine::CheckParam("-dedicated"))
return;
if (argc != 2)
{
V_printf("connect_friend <steamid>\n");
return;
}
uint64_t nFriendID = 0;
V_sscanf(argv[1], "%llu\n", &nFriendID);
V_printf("Connecting to %llu\n",nFriendID);
INetworking::JoinServer(nFriendID);
};
ConCommand ConnectCmd("connect", INetworking_ConnectFriend);

View File

@@ -54,9 +54,6 @@ void IServer::Think( float fDelta )
/* tickrate */
while(g_fAccumulator>=fTickrate)
{
#ifdef STEAM_ENABLED
SteamGameServer_RunCallbacks();
#endif
IInput::Frame();
IConsole::Execute();
g_fAccumulator-=fTickrate;
@@ -66,6 +63,7 @@ void IServer::Think( float fDelta )
entity->Sync(0, 0);
}
px_frame(px, fTickrate);
INetworking::Frame();
}
for (auto &entity: g_entities)
{

View File

@@ -191,7 +191,7 @@ void IVulkan::Frame()
{
mat4 perspective;
glm_mat4_inv(g_cameraView, g_cameraDataMap->viewprojection);
glm_perspective(glm_rad(90),(float)g_nWindowWidth/g_nWindowHeight, 0.01, 100, perspective);
glm_perspective(glm_rad(68),(float)g_nWindowWidth/g_nWindowHeight, 0.01, 10000, perspective);
glm_rotate(perspective, glm_rad(90), (vec4){1,0,0,0});
glm_scale(perspective, (vec4){1,-1,1,1});
glm_rotate(perspective, glm_rad(90), (vec4){0,0,1,0});
@@ -270,28 +270,26 @@ void IVulkan::Frame()
}
);
VkImageCopy imageCopyRegion = {};
VkImageBlit imageCopyRegion = {};
imageCopyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageCopyRegion.srcSubresource.mipLevel = 0;
imageCopyRegion.srcSubresource.baseArrayLayer = 0;
imageCopyRegion.srcSubresource.layerCount = 1;
imageCopyRegion.srcOffset = {0, 0, 0};
imageCopyRegion.srcOffsets[0] = {0, 0, 0};
imageCopyRegion.srcOffsets[1] = {(int)g_nWindowWidth, (int)g_nWindowHeight, 1};
imageCopyRegion.dstSubresource = imageCopyRegion.srcSubresource;
imageCopyRegion.dstOffset = {0, 0, 0};
imageCopyRegion.dstOffsets[0] = {0, 0, 0};
imageCopyRegion.dstOffsets[1] = {(int)g_nWindowWidth, (int)g_nWindowHeight, 1};
imageCopyRegion.extent.width = g_nWindowWidth;
imageCopyRegion.extent.height = g_nWindowHeight;
imageCopyRegion.extent.depth = 1;
vkCmdCopyImage(
vkCmdBlitImage(
g_vkCommandBuffer,
((CVkImage*)g_meshColor)->m_image.m_image,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
g_swapchainImage,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1,
&imageCopyRegion
1, &imageCopyRegion,
VK_FILTER_NEAREST
);
for (auto &step: g_StepShading)
step.pPipeline->Frame(0);

View File

@@ -74,8 +74,8 @@ void IVideo_SwapchainInit()
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_vkPhysicalDevice, g_surface, &surfaceCapatibilities);
const VkFormat preferedSurfaceFormats[] = {
VK_FORMAT_R8G8B8A8_UNORM,
VK_FORMAT_B8G8R8A8_UNORM,
VK_FORMAT_R8G8B8A8_UNORM,
};
uint32_t numSurfaceFormats = 0;
@@ -88,9 +88,14 @@ void IVideo_SwapchainInit()
{
for (int i = 0; i < sizeof(preferedSurfaceFormats)/sizeof(VkFormat); i++)
{
selectedFormat = surfaceFormats[i];
if (format.format == preferedSurfaceFormats[i])
{
selectedFormat = format;
goto formatPicked;
}
}
}
formatPicked:
uint32_t numSurfacePresentModes = 0;
vkGetPhysicalDeviceSurfacePresentModesKHR(g_vkPhysicalDevice, g_surface, &numSurfacePresentModes, NULL);