Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add trap_GetPings, so that engine does not mutate playerstate #1450

Open
wants to merge 2 commits into
base: for-0.56.0/sync
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions src/engine/qcommon/msg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<const int *>( reinterpret_cast<const byte *>( from ) + field->offset );
auto toF = reinterpret_cast<const int *>( reinterpret_cast<const byte *>( to ) + field->offset );

if (field->bits == STATS_GROUP_FIELD
? memcmp(fromF, toF, sizeof(int) * STATS_GROUP_NUM_STATS)
Expand All @@ -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<const int *>( reinterpret_cast<const byte *>( from ) + field->offset );
auto toF = reinterpret_cast<const int *>( reinterpret_cast<const byte *>( to ) + field->offset );

if (field->bits == STATS_GROUP_FIELD)
{
Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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<const int *>( reinterpret_cast<const byte *>( from ) + field->offset );
auto toF = reinterpret_cast<int *>( reinterpret_cast<byte *>( to ) + field->offset );

if ( !MSG_ReadBits( msg, 1 ) )
{
Expand Down
1 change: 0 additions & 1 deletion src/engine/qcommon/q_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/engine/qcommon/qcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 );

//============================================================================

Expand Down
10 changes: 5 additions & 5 deletions src/engine/server/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
5 changes: 5 additions & 0 deletions src/engine/server/sg_msgdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -102,6 +103,10 @@ using GetTimeStringMsg = IPC::SyncMessage<
IPC::Message<IPC::Id<VM::QVM, G_GET_TIME_STRING>, int, std::string, qtime_t>,
IPC::Reply<std::string>
>;
using GetPingsMsg = IPC::SyncMessage<
IPC::Message<IPC::Id<VM::QVM, G_GET_PINGS>>,
IPC::Reply<std::vector<int>>
>;

using BotAllocateClientMsg = IPC::SyncMessage<
IPC::Message<IPC::Id<VM::QVM, BOT_ALLOCATE_CLIENT>>,
Expand Down
2 changes: 1 addition & 1 deletion src/engine/server/sv_ccmds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 );

Expand Down
6 changes: 1 addition & 5 deletions src/engine/server/sv_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
}
}
Expand Down Expand Up @@ -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;
}
}

Expand Down
20 changes: 15 additions & 5 deletions src/engine/server/sv_sgame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<sharedEntity_t *>( 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 )
{
Expand Down Expand Up @@ -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<char*>(shmRegion.GetBase());
sv.gentities = reinterpret_cast<sharedEntity_t*>(base);
byte* base = static_cast<byte*>(shmRegion.GetBase());
sv.gentities = base;
sv.gentitySize = sizeofGEntity_t;
sv.num_entities = numGEntities;

sv.gameClients = reinterpret_cast<OpaquePlayerState*>(base + MAX_GENTITIES * size_t(sizeofGEntity_t));
sv.gameClients = base + MAX_GENTITIES * size_t(sizeofGEntity_t);
sv.gameClientSize = sizeofGameClient;
}

Expand Down Expand Up @@ -564,6 +564,16 @@ void GameVM::QVMSyscall(int syscallNum, Util::Reader& reader, IPC::Channel& chan
});
break;

case G_GET_PINGS:
IPC::HandleMsg<GetPingsMsg>(channel, std::move(reader), [this](std::vector<int>& 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<BotAllocateClientMsg>(channel, std::move(reader), [this](int& output) {
output = SV_BotAllocateClient();
Expand Down
2 changes: 1 addition & 1 deletion src/engine/server/sv_snapshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions src/shared/server/sg_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int> trap_GetPings()
{
std::vector<int> pings;
VM::SendMsg<GetPingsMsg>(pings);
return pings;
}


int trap_BotAllocateClient()
{
int res;
Expand Down
1 change: 1 addition & 0 deletions src/shared/server/sg_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<int> trap_GetPings();

#endif