From 050c92e0d7f4c62dc73695bd48d4a385cf0370bb Mon Sep 17 00:00:00 2001 From: slipher Date: Tue, 4 Jun 2024 13:41:55 -0500 Subject: [PATCH 1/2] Add trap_GetPings; remove ping from playerstate --- src/engine/qcommon/q_shared.h | 1 - src/engine/server/sg_msgdef.h | 5 +++++ src/engine/server/sv_main.cpp | 4 ---- src/engine/server/sv_sgame.cpp | 10 ++++++++++ src/shared/server/sg_api.cpp | 9 +++++++++ src/shared/server/sg_api.h | 1 + 6 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/engine/qcommon/q_shared.h b/src/engine/qcommon/q_shared.h index 62d738e258..e1e2a20f61 100644 --- a/src/engine/qcommon/q_shared.h +++ b/src/engine/qcommon/q_shared.h @@ -1909,7 +1909,6 @@ union OpaquePlayerState { struct { // These fields must be identical to ones at the start of playerState_t vec3_t origin; - int ping; // shouldn't even be here? int persistant[16]; int viewheight; int clientNum; diff --git a/src/engine/server/sg_msgdef.h b/src/engine/server/sg_msgdef.h index 73b2239a37..a5b45d8d15 100644 --- a/src/engine/server/sg_msgdef.h +++ b/src/engine/server/sg_msgdef.h @@ -45,6 +45,7 @@ enum gameImport_t G_GEN_FINGERPRINT, G_GET_PLAYER_PUBKEY, G_GET_TIME_STRING, + G_GET_PINGS, BOT_ALLOCATE_CLIENT, BOT_FREE_CLIENT, @@ -102,6 +103,10 @@ using GetTimeStringMsg = IPC::SyncMessage< IPC::Message, int, std::string, qtime_t>, IPC::Reply >; +using GetPingsMsg = IPC::SyncMessage< + IPC::Message>, + IPC::Reply> +>; using BotAllocateClientMsg = IPC::SyncMessage< IPC::Message>, diff --git a/src/engine/server/sv_main.cpp b/src/engine/server/sv_main.cpp index 1fc7ec2096..e35f6da21c 100644 --- a/src/engine/server/sv_main.cpp +++ b/src/engine/server/sv_main.cpp @@ -1210,10 +1210,6 @@ void SV_CalcPings() cl->ping = 999; } } - - // let the game module know about the ping - OpaquePlayerState* ps = SV_GameClientNum( i ); - ps->ping = cl->ping; } } diff --git a/src/engine/server/sv_sgame.cpp b/src/engine/server/sv_sgame.cpp index 8e7eb5b596..9498b2fe15 100644 --- a/src/engine/server/sv_sgame.cpp +++ b/src/engine/server/sv_sgame.cpp @@ -564,6 +564,16 @@ void GameVM::QVMSyscall(int syscallNum, Util::Reader& reader, IPC::Channel& chan }); break; + case G_GET_PINGS: + IPC::HandleMsg(channel, std::move(reader), [this](std::vector& pings) { + int count = sv_maxclients->integer; + pings.resize(count); + for (int i = 0; i < count; i++) { + pings[i] = svs.clients[i].ping; + } + }); + break; + case BOT_ALLOCATE_CLIENT: IPC::HandleMsg(channel, std::move(reader), [this](int& output) { output = SV_BotAllocateClient(); diff --git a/src/shared/server/sg_api.cpp b/src/shared/server/sg_api.cpp index faf17a9af0..27768fe553 100644 --- a/src/shared/server/sg_api.cpp +++ b/src/shared/server/sg_api.cpp @@ -144,6 +144,15 @@ void trap_GetTimeString(char *buffer, int size, const char *format, const qtime_ Q_strncpyz(buffer, text.c_str(), size); } +// length of returned vector is sv_maxclients +std::vector trap_GetPings() +{ + std::vector pings; + VM::SendMsg(pings); + return pings; +} + + int trap_BotAllocateClient() { int res; diff --git a/src/shared/server/sg_api.h b/src/shared/server/sg_api.h index cd7a08be88..9042f19b7c 100644 --- a/src/shared/server/sg_api.h +++ b/src/shared/server/sg_api.h @@ -53,5 +53,6 @@ int trap_RSA_GenerateMessage( const char *public_key, char *clearte void trap_GenFingerprint( const char *pubkey, int size, char *buffer, int bufsize ); void trap_GetPlayerPubkey( int clientNum, char *pubkey, int size ); void trap_GetTimeString( char *buffer, int size, const char *format, const qtime_t *tm ); +std::vector trap_GetPings(); #endif From b99ea645b2491faa298a41cddee8cbbc13e2f044 Mon Sep 17 00:00:00 2001 From: slipher Date: Tue, 4 Jun 2024 14:37:12 -0500 Subject: [PATCH 2/2] Make shared memory player state pointers const --- src/engine/qcommon/msg.cpp | 19 +++++++++---------- src/engine/qcommon/qcommon.h | 4 ++-- src/engine/server/server.h | 10 +++++----- src/engine/server/sv_ccmds.cpp | 2 +- src/engine/server/sv_main.cpp | 2 +- src/engine/server/sv_sgame.cpp | 10 +++++----- src/engine/server/sv_snapshot.cpp | 2 +- 7 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/engine/qcommon/msg.cpp b/src/engine/qcommon/msg.cpp index c2a8308607..ed72b56b15 100644 --- a/src/engine/qcommon/msg.cpp +++ b/src/engine/qcommon/msg.cpp @@ -1336,10 +1336,10 @@ MSG_WriteDeltaPlayerstate ============= */ -void MSG_WriteDeltaPlayerstate( msg_t *msg, OpaquePlayerState *from, OpaquePlayerState *to ) +void MSG_WriteDeltaPlayerstate( + msg_t *msg, const OpaquePlayerState *from, const OpaquePlayerState *to ) { int lc; - int *fromF, *toF; float fullFloat; int trunc; int startBit, endBit; @@ -1383,8 +1383,8 @@ void MSG_WriteDeltaPlayerstate( msg_t *msg, OpaquePlayerState *from, OpaquePlaye for ( int i = 0; i < numFields; i++ ) { netField_t* field = &playerStateFields[i]; - fromF = ( int * )( ( byte * ) from + field->offset ); - toF = ( int * )( ( byte * ) to + field->offset ); + auto fromF = reinterpret_cast( reinterpret_cast( from ) + field->offset ); + auto toF = reinterpret_cast( reinterpret_cast( to ) + field->offset ); if (field->bits == STATS_GROUP_FIELD ? memcmp(fromF, toF, sizeof(int) * STATS_GROUP_NUM_STATS) @@ -1401,8 +1401,8 @@ void MSG_WriteDeltaPlayerstate( msg_t *msg, OpaquePlayerState *from, OpaquePlaye for ( int i = 0; i < lc; i++ ) { netField_t* field = &playerStateFields[i]; - fromF = ( int * )( ( byte * ) from + field->offset ); - toF = ( int * )( ( byte * ) to + field->offset ); + auto fromF = reinterpret_cast( reinterpret_cast( from ) + field->offset ); + auto toF = reinterpret_cast( reinterpret_cast( to ) + field->offset ); if (field->bits == STATS_GROUP_FIELD) { @@ -1486,12 +1486,11 @@ static void ReadStatsGroup(msg_t* msg, int* to, const netField_t& field) MSG_ReadDeltaPlayerstate =================== */ -void MSG_ReadDeltaPlayerstate( msg_t *msg, OpaquePlayerState *from, OpaquePlayerState *to ) +void MSG_ReadDeltaPlayerstate( msg_t *msg, const OpaquePlayerState *from, OpaquePlayerState *to ) { int lc; int startBit, endBit; int print; - int *fromF, *toF; int trunc; if (playerStateFields.empty()) @@ -1537,8 +1536,8 @@ void MSG_ReadDeltaPlayerstate( msg_t *msg, OpaquePlayerState *from, OpaquePlayer for ( int i = 0; i < lc; i++ ) { netField_t* field = &playerStateFields[i]; - fromF = ( int * )( ( byte * ) from + field->offset ); - toF = ( int * )( ( byte * ) to + field->offset ); + auto fromF = reinterpret_cast( reinterpret_cast( from ) + field->offset ); + auto toF = reinterpret_cast( reinterpret_cast( to ) + field->offset ); if ( !MSG_ReadBits( msg, 1 ) ) { diff --git a/src/engine/qcommon/qcommon.h b/src/engine/qcommon/qcommon.h index c5df5d5740..6e8a60a886 100644 --- a/src/engine/qcommon/qcommon.h +++ b/src/engine/qcommon/qcommon.h @@ -96,8 +96,8 @@ void MSG_WriteDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to, void MSG_ReadDeltaEntity( msg_t *msg, const entityState_t *from, entityState_t *to, int number ); void MSG_InitNetcodeTables(NetcodeTable playerStateTable, int playerStateSize); -void MSG_WriteDeltaPlayerstate( msg_t *msg, OpaquePlayerState *from, OpaquePlayerState *to ); -void MSG_ReadDeltaPlayerstate( msg_t *msg, OpaquePlayerState *from, OpaquePlayerState *to ); +void MSG_WriteDeltaPlayerstate( msg_t *msg, const OpaquePlayerState *from, const OpaquePlayerState *to ); +void MSG_ReadDeltaPlayerstate( msg_t *msg, const OpaquePlayerState *from, OpaquePlayerState *to ); //============================================================================ diff --git a/src/engine/server/server.h b/src/engine/server/server.h index bed3e0b3db..e76c8148e4 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -82,12 +82,12 @@ struct server_t const char *entityParsePoint; // used during game VM init // the game virtual machine will update these on init and changes - sharedEntity_t *gentities; - int gentitySize; + byte *gentities; // points to the sgame's array of gentity_t + int gentitySize; // >= sizeof(sharedEntity_t) - game can have unlimited amount of private data int num_entities; // current number, <= MAX_GENTITIES - OpaquePlayerState *gameClients; - int gameClientSize; // will be > sizeof(playerState_t) due to game private data + const byte *gameClients; // points to the sgame's array of playerState_t in shared memory + int gameClientSize; // will be <= sizeof(OpaquePlayerState) int restartTime; int time; @@ -393,7 +393,7 @@ void SV_SendClientIdle( client_t *client ); // sv_sgame.c // sharedEntity_t *SV_GentityNum( int num ); -OpaquePlayerState *SV_GameClientNum( int num ); +const OpaquePlayerState *SV_GameClientNum( int num ); svEntity_t *SV_SvEntityForGentity( sharedEntity_t *gEnt ); void SV_InitGameProgs(); diff --git a/src/engine/server/sv_ccmds.cpp b/src/engine/server/sv_ccmds.cpp index e8f0be37a2..08b926f9ea 100644 --- a/src/engine/server/sv_ccmds.cpp +++ b/src/engine/server/sv_ccmds.cpp @@ -338,7 +338,7 @@ class StatusCmd: public Cmd::StaticCmd connection = "ERROR"; } } - OpaquePlayerState* ps = SV_GameClientNum( i ); + const OpaquePlayerState* ps = SV_GameClientNum( i ); const char *address = NET_AdrToString( cl.netchan.remoteAddress ); diff --git a/src/engine/server/sv_main.cpp b/src/engine/server/sv_main.cpp index e35f6da21c..eb47db562e 100644 --- a/src/engine/server/sv_main.cpp +++ b/src/engine/server/sv_main.cpp @@ -496,7 +496,7 @@ static void SVC_Status( const netadr_t& from, const Cmd::Args& args ) if ( cl->state >= clientState_t::CS_CONNECTED ) { - OpaquePlayerState* ps = SV_GameClientNum( i ); + const OpaquePlayerState* ps = SV_GameClientNum( i ); status += Str::Format( "%i %i \"%s\"\n", ps->persistant[ PERS_SCORE ], cl->ping, cl->name ); } } diff --git a/src/engine/server/sv_sgame.cpp b/src/engine/server/sv_sgame.cpp index 9498b2fe15..7de233054b 100644 --- a/src/engine/server/sv_sgame.cpp +++ b/src/engine/server/sv_sgame.cpp @@ -60,10 +60,10 @@ sharedEntity_t *SV_GentityNum( int num ) Sys::Drop( "SV_GentityNum: bad num %d", num ); } - return ( sharedEntity_t * )( ( byte * ) sv.gentities + sv.gentitySize * ( num ) ); + return reinterpret_cast( sv.gentities + sv.gentitySize * num ); } -OpaquePlayerState *SV_GameClientNum( int num ) +const OpaquePlayerState *SV_GameClientNum( int num ) { if ( num < 0 || num >= sv_maxclients->integer || sv.gameClients == nullptr ) { @@ -194,12 +194,12 @@ void SV_LocateGameData( const IPC::SharedMemory& shmRegion, int numGEntities, in if ( int64_t(shmRegion.GetSize()) < int64_t(MAX_GENTITIES) * sizeofGEntity_t + int64_t(sv_maxclients->integer) * sizeofGameClient ) Sys::Drop( "SV_LocateGameData: Shared memory region too small" ); - char* base = static_cast(shmRegion.GetBase()); - sv.gentities = reinterpret_cast(base); + byte* base = static_cast(shmRegion.GetBase()); + sv.gentities = base; sv.gentitySize = sizeofGEntity_t; sv.num_entities = numGEntities; - sv.gameClients = reinterpret_cast(base + MAX_GENTITIES * size_t(sizeofGEntity_t)); + sv.gameClients = base + MAX_GENTITIES * size_t(sizeofGEntity_t); sv.gameClientSize = sizeofGameClient; } diff --git a/src/engine/server/sv_snapshot.cpp b/src/engine/server/sv_snapshot.cpp index 8063e7be7b..b0732dac57 100644 --- a/src/engine/server/sv_snapshot.cpp +++ b/src/engine/server/sv_snapshot.cpp @@ -690,7 +690,7 @@ static void SV_BuildClientSnapshot( client_t *client ) } // grab the current playerState_t - OpaquePlayerState* ps = SV_GameClientNum( client - svs.clients ); + const OpaquePlayerState* ps = SV_GameClientNum( client - svs.clients ); memcpy(&frame->ps, ps, sizeof(frame->ps)); // never send client's own entity, because it can