diff --git a/engine/client/console.c b/engine/client/console.c index 6ae84e16..78c0a81f 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -2043,8 +2043,8 @@ void Con_DrawDebug( void ) if( scr_download->value != -1.0f ) { - Q_snprintf( dlstring, sizeof( dlstring ), "Downloading [%d remaining]: ^2%s^7 %5.1f%%", - host.downloadcount, host.downloadfile, scr_download->value, Sys_DoubleTime() - timeStart ); + Q_snprintf( dlstring, sizeof( dlstring ), "Downloading [%d remaining]: ^2%s^7 %5.1f%% (%f elapsed)", + host.downloadcount, host.downloadfile, scr_download->value, Sys_DoubleTime() - timeStart ); x = glState.width - 400; y = con.curFont->charHeight * 1.05f; Con_DrawString( x, y, dlstring, g_color_table[7] ); @@ -2199,7 +2199,7 @@ void Con_DrawSolidConsole( int lines ) memcpy( color, g_color_table[7], sizeof( color )); - Q_snprintf( curbuild, MAX_STRING, "Xash3D %i/%g (hw build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( )); + Q_snprintf( curbuild, MAX_STRING, "%s %i/%s (hw build %i)", XASH_ENGINE_NAME, PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( )); Con_DrawStringLen( curbuild, &stringLen, &charH ); start = glState.width - stringLen; stringLen = Con_StringLength( curbuild ); @@ -2349,8 +2349,8 @@ void Con_DrawVersion( void ) } if( host.force_draw_version || draw_version ) - Q_snprintf( curbuild, MAX_STRING, "Xash3D v%i/%g (build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( )); - else Q_snprintf( curbuild, MAX_STRING, "v%i/%g (build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( )); + Q_snprintf( curbuild, MAX_STRING, "%s v%i/%s (build %i)", XASH_ENGINE_NAME, PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( )); + else Q_snprintf( curbuild, MAX_STRING, "v%i/%s (build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( )); Con_DrawStringLen( curbuild, &stringLen, &charH ); start = glState.width - stringLen * 1.05f; stringLen = Con_StringLength( curbuild ); diff --git a/engine/client/vid_common.c b/engine/client/vid_common.c index 3a3c1aed..5553c745 100644 --- a/engine/client/vid_common.c +++ b/engine/client/vid_common.c @@ -20,7 +20,7 @@ GNU General Public License for more details. #include "input.h" #include "vid_common.h" -#define WINDOW_NAME "Xash3D Window" // Half-Life +#define WINDOW_NAME XASH_ENGINE_NAME " Window" // Half-Life convar_t *gl_extensions; convar_t *gl_texture_anisotropy; diff --git a/engine/common/build.c b/engine/common/build.c index b7f5df34..89af30aa 100644 --- a/engine/common/build.c +++ b/engine/common/build.c @@ -50,4 +50,92 @@ int Q_buildnum( void ) #else return 3847; #endif -} \ No newline at end of file +} + +/* +============ +Q_buildos + +Returns current name of operating system. Without any spaces. +============ +*/ +const char *Q_buildos( void ) +{ + const char *osname; + +#if defined(_WIN32) && defined(_MSC_VER) + osname = "Win32"; +#elif defined(_WIN32) && defined(__MINGW32__) + osname = "Win32-MinGW"; +#elif defined(__ANDROID__) + osname = "Android"; +#elif defined(__linux__) + osname = "Linux"; +#elif defined(__APPLE__) + osname = "Apple"; +#elif defined(__FreeBSD__) + osname = "FreeBSD"; +#elif defined(__NetBSD__) + osname = "NetBSD"; +#elif defined(__OpenBSD__) + osname = "OpenBSD"; +#elif defined __EMSCRIPTEN__ + osname = "Emscripten"; +#else +#error "Place your operating system name here! If this is a mistake, try to fix conditions above and report a bug" +#endif + + return osname; +} + +/* +============ +Q_buildos + +Returns current name of operating system. Without any spaces. +============ +*/ +const char *Q_buildarch( void ) +{ + const char *archname; + +#if defined( __x86_64__) || defined(_M_X64) + archname = "amd64"; +#elif defined(__i386__) || defined(_X86_) || defined(_M_IX86) + archname = "i386"; +#elif defined __aarch64__ + archname = "aarch64"; +#elif defined __arm__ || defined _M_ARM + archname = "arm"; +#elif defined __mips__ + archname = "mips"; +#elif defined __EMSCRIPTEN__ + archname = "javascript"; +#else +#error "Place your architecture name here! If this is a mistake, try to fix conditions above and report a bug" +#endif + + return archname; +} + +/* +============= +Q_buildcommit + +Returns a short hash of current commit in VCS as string. +XASH_BUILD_COMMIT must be passed in quotes + +if XASH_BUILD_COMMIT is not defined, +Q_buildcommit will identify this build as release or "notset" +============= +*/ +const char *Q_buildcommit( void ) +{ +#ifdef XASH_BUILD_COMMIT + return XASH_BUILD_COMMIT; +#elif defined(XASH_RELEASE) // don't check it elsewhere to avoid random bugs + return "release"; +#else + return "notset"; +#endif +} diff --git a/engine/common/com_strings.h b/engine/common/com_strings.h index cb37bb3e..8f0b82f6 100644 --- a/engine/common/com_strings.h +++ b/engine/common/com_strings.h @@ -59,4 +59,6 @@ GNU General Public License for more details. #define DEFAULT_UPDATE_PAGE "https://github.com/FWGS/xash3d-fwgs/releases/latest" +#define XASH_ENGINE_NAME "Xash3D FWGS" + #endif//COM_STRINGS_H diff --git a/engine/common/common.h b/engine/common/common.h index db26b443..4e29918e 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -168,7 +168,7 @@ typedef enum #include "cvar.h" #include "con_nprint.h" -#define XASH_VERSION 0.99f // engine current version +#define XASH_VERSION "0.99" // engine current version // PERFORMANCE INFO #define MIN_FPS 20.0 // host minimum fps value for maxfps. @@ -539,7 +539,7 @@ long FS_Read( file_t *file, void *buffer, size_t buffersize ); int FS_VPrintf( file_t *file, const char *format, va_list ap ); int FS_Seek( file_t *file, long offset, int whence ); int FS_Gets( file_t *file, byte *string, size_t bufsize ); -int FS_Printf( file_t *file, const char *format, ... ); +int FS_Printf( file_t *file, const char *format, ... ) _format( 2 ); long FS_FileSize( const char *filename, qboolean gamedironly ); long FS_FileTime( const char *filename, qboolean gamedironly ); int FS_Print( file_t *file, const char *msg ); @@ -775,6 +775,10 @@ uint Sound_GetApproxWavePlayLen( const char *filepath ); // build.c // int Q_buildnum( void ); +const char *Q_buildos( void ); +const char *Q_buildarch( void ); +const char *Q_buildcommit( void ); + // // host.c @@ -782,7 +786,7 @@ int Q_buildnum( void ); void EXPORT Host_Shutdown( void ); int Host_CompareFileTime( long ft1, long ft2 ); void Host_NewInstance( const char *name, const char *finalmsg ); -void Host_EndGame( qboolean abort, const char *message, ... ); +void Host_EndGame( qboolean abort, const char *message, ... ) _format( 2 ); void Host_AbortCurrentFrame( void ); void Host_WriteServerConfig( const char *name ); void Host_WriteOpenGLConfig( void ); @@ -791,7 +795,7 @@ void Host_WriteConfig( void ); qboolean Host_IsLocalGame( void ); qboolean Host_IsLocalClient( void ); void Host_ShutdownServer( void ); -void Host_Error( const char *error, ... ); +void Host_Error( const char *error, ... ) _format( 1 ); void Host_PrintEngineFeatures( void ); void Host_Frame( float time ); void Host_InitDecals( void ); @@ -855,9 +859,9 @@ void pfnGetGameDir( char *szGetGameDir ); int pfnDecalIndex( const char *m ); int pfnGetModelType( model_t *mod ); int pfnIsMapValid( char *filename ); -void Con_Reportf( char *szFmt, ... ); -void Con_DPrintf( char *fmt, ... ); -void Con_Printf( char *szFmt, ... ); +void Con_Reportf( char *szFmt, ... ) _format( 1 ); +void Con_DPrintf( char *fmt, ... ) _format( 1 ); +void Con_Printf( char *szFmt, ... ) _format( 1 ); int pfnNumberOfEntities( void ); int pfnIsInGame( void ); float pfnTime( void ); @@ -975,11 +979,11 @@ struct pmtrace_s *PM_TraceLine( float *start, float *end, int flags, int usehull void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float attn, int flags, int pitch ); void SV_StartMusic( const char *curtrack, const char *looptrack, long position ); void SV_CreateDecal( sizebuf_t *msg, const float *origin, int decalIndex, int entityIndex, int modelIndex, int flags, float scale ); -void Log_Printf( const char *fmt, ... ); +void Log_Printf( const char *fmt, ... ) _format( 1 ); struct sizebuf_s *SV_GetReliableDatagram( void ); -void SV_BroadcastCommand( const char *fmt, ... ); +void SV_BroadcastCommand( const char *fmt, ... ) _format( 1 ); qboolean SV_RestoreCustomDecal( struct decallist_s *entry, edict_t *pEdict, qboolean adjacent ); -void SV_BroadcastPrintf( sv_client_t *ignore, char *fmt, ... ); +void SV_BroadcastPrintf( sv_client_t *ignore, char *fmt, ... ) _format( 2 ); int R_CreateDecalList( struct decallist_s *pList ); void R_DecalRemoveAll( int texture ); void R_ClearAllDecals( void ); @@ -987,7 +991,7 @@ void R_ClearStaticEntities( void ); qboolean S_StreamGetCurrentState( char *currentTrack, char *loopTrack, int *position ); struct cl_entity_s *CL_GetEntityByIndex( int index ); struct player_info_s *CL_GetPlayerInfo( int playerIndex ); -void CL_ServerCommand( qboolean reliable, char *fmt, ... ); +void CL_ServerCommand( qboolean reliable, char *fmt, ... ) _format( 2 ); void CL_HudMessage( const char *pMessage ); const char *CL_MsgInfo( int cmd ); void SV_DrawDebugTriangles( void ); @@ -1033,10 +1037,10 @@ long SCR_GetAudioChunk( char *rawdata, long length ); wavdata_t *SCR_GetMovieInfo( void ); void SCR_Shutdown( void ); void Con_Print( const char *txt ); -void Con_NPrintf( int idx, char *fmt, ... ); -void Con_NXPrintf( con_nprint_t *info, char *fmt, ... ); -void UI_NPrintf( int idx, char *fmt, ... ); -void UI_NXPrintf( con_nprint_t *info, char *fmt, ... ); +void Con_NPrintf( int idx, char *fmt, ... ) _format( 2 ); +void Con_NXPrintf( con_nprint_t *info, char *fmt, ... ) _format( 2 ); +void UI_NPrintf( int idx, char *fmt, ... ) _format( 2 ); +void UI_NXPrintf( con_nprint_t *info, char *fmt, ... ) _format( 2 ); char *Info_ValueForKey( const char *s, const char *key ); void Info_RemovePrefixedKeys( char *start, char prefix ); qboolean Info_RemoveKey( char *s, const char *key ); diff --git a/engine/common/crtlib.h b/engine/common/crtlib.h index f622010c..6f28b3b6 100644 --- a/engine/common/crtlib.h +++ b/engine/common/crtlib.h @@ -16,6 +16,12 @@ GNU General Public License for more details. #ifndef STDLIB_H #define STDLIB_H +#ifdef __GNUC__ +#define _format(x) __attribute__((format(printf, x, x+1))) +#else +#define _format(x) +#endif + // timestamp modes enum { @@ -97,11 +103,11 @@ char *Q_stristr( const char *string, const char *string2 ); char *Q_strstr( const char *string, const char *string2 ); #define Q_vsprintf( buffer, format, args ) Q_vsnprintf( buffer, 99999, format, args ) int Q_vsnprintf( char *buffer, size_t buffersize, const char *format, va_list args ); -int Q_snprintf( char *buffer, size_t buffersize, const char *format, ... ); -int Q_sprintf( char *buffer, const char *format, ... ); +int Q_snprintf( char *buffer, size_t buffersize, const char *format, ... ) _format( 3 ); +int Q_sprintf( char *buffer, const char *format, ... ) _format( 2 ); #define Q_memprint( val ) Q_pretifymem( val, 2 ) char *Q_pretifymem( float value, int digitsafterdecimal ); -char *va( const char *format, ... ); +char *va( const char *format, ... ) _format( 1 ); // // zone.c @@ -127,4 +133,4 @@ void Mem_PrintStats( void ); #define Mem_IsAllocated( mem ) Mem_IsAllocatedExt( NULL, mem ) #define Mem_Check() _Mem_Check( __FILE__, __LINE__ ) -#endif//STDLIB_H \ No newline at end of file +#endif//STDLIB_H diff --git a/engine/common/host.c b/engine/common/host.c index 7169dd77..5baefccc 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -878,7 +878,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa host_limitlocal = Cvar_Get( "host_limitlocal", "0", 0, "apply cl_cmdrate and rate to loopback connection" ); con_gamemaps = Cvar_Get( "con_mapfilter", "1", FCVAR_ARCHIVE, "when true show only maps in game folder" ); build = Cvar_Get( "build", va( "%i", Q_buildnum()), FCVAR_READ_ONLY, "returns a current build number" ); - ver = Cvar_Get( "ver", va( "%i/%g (hw build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum()), FCVAR_READ_ONLY, "shows an engine version" ); + ver = Cvar_Get( "ver", va( "%i/%s (hw build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum()), FCVAR_READ_ONLY, "shows an engine version" ); Mod_Init(); NET_Init(); diff --git a/engine/common/netchan.h b/engine/common/netchan.h index 6805ea45..7c5c5b73 100644 --- a/engine/common/netchan.h +++ b/engine/common/netchan.h @@ -23,6 +23,7 @@ GNU General Public License for more details. ========================================================== */ +#include "crtlib.h" #include "net_buffer.h" // 0 == regular, 1 == file stream @@ -221,7 +222,7 @@ int Netchan_CreateFileFragments( netchan_t *chan, const char *filename ); void Netchan_Transmit( netchan_t *chan, int lengthInBytes, byte *data ); void Netchan_TransmitBits( netchan_t *chan, int lengthInBits, byte *data ); void Netchan_OutOfBand( int net_socket, netadr_t adr, int length, byte *data ); -void Netchan_OutOfBandPrint( int net_socket, netadr_t adr, char *format, ... ); +void Netchan_OutOfBandPrint( int net_socket, netadr_t adr, char *format, ... ) _format( 3 ); qboolean Netchan_Process( netchan_t *chan, sizebuf_t *msg ); void Netchan_UpdateProgress( netchan_t *chan ); qboolean Netchan_IncomingReady( netchan_t *chan ); @@ -231,4 +232,4 @@ void Netchan_ReportFlow( netchan_t *chan ); void Netchan_FragSend( netchan_t *chan ); void Netchan_Clear( netchan_t *chan ); -#endif//NET_MSG_H \ No newline at end of file +#endif//NET_MSG_H diff --git a/engine/common/system.h b/engine/common/system.h index 8c59eb5a..c8bb68a9 100644 --- a/engine/common/system.h +++ b/engine/common/system.h @@ -50,6 +50,7 @@ extern "C" { #include "xash3d_types.h" #include "const.h" +#include "crtlib.h" #define ASSERT( exp ) if(!( exp )) Sys_Error( "assert failed at %s:%i\n", __FILE__, __LINE__ ) @@ -81,8 +82,8 @@ double Sys_DoubleTime( void ); char *Sys_GetClipboardData( void ); char *Sys_GetCurrentUser( void ); int Sys_CheckParm( const char *parm ); -void Sys_Warn( const char *format, ... ); -void Sys_Error( const char *error, ... ); +void Sys_Warn( const char *format, ... ) _format( 1 ); +void Sys_Error( const char *error, ... ) _format( 1 ); qboolean Sys_LoadLibrary( dll_info_t *dll ); void* Sys_GetProcAddress( dll_info_t *dll, const char* name ); qboolean Sys_FreeLibrary( dll_info_t *dll ); @@ -128,7 +129,7 @@ char *Wcon_Input( void ); // text messages #define Msg Con_Printf -void MsgDev( int level, const char *pMsg, ... ); +void MsgDev( int level, const char *pMsg, ... ) _format( 2 ); #ifdef __cplusplus } diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 55ca5f6f..b3a01916 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -2134,7 +2134,7 @@ SV_StartMusic void SV_StartMusic( const char *curtrack, const char *looptrack, long position ) { MSG_BeginServerCmd( &sv.multicast, svc_stufftext ); - MSG_WriteString( &sv.multicast, va( "music \"%s\" \"%s\" %i\n", curtrack, looptrack, position )); + MSG_WriteString( &sv.multicast, va( "music \"%s\" \"%s\" %li\n", curtrack, looptrack, position )); SV_Multicast( MSG_ALL, NULL, NULL, false, false ); } @@ -2404,6 +2404,7 @@ pfnClientCommand ========= */ +void pfnClientCommand( edict_t* pEdict, char* szFmt, ... ) _format( 2 ); void pfnClientCommand( edict_t* pEdict, char* szFmt, ... ) { sv_client_t *cl; @@ -2834,6 +2835,7 @@ pfnAlertMessage ============= */ +static void pfnAlertMessage( ALERT_TYPE type, char *szFmt, ... ) _format( 2 ); static void pfnAlertMessage( ALERT_TYPE type, char *szFmt, ... ) { char buffer[2048]; @@ -2887,6 +2889,7 @@ pfnEngineFprintf OBSOLETE, UNUSED ============= */ +static void pfnEngineFprintf( FILE *pfile, char *szFmt, ... ) _format( 2 ); static void pfnEngineFprintf( FILE *pfile, char *szFmt, ... ) { } diff --git a/engine/server/sv_log.c b/engine/server/sv_log.c index f21d29f5..8c50e5a8 100644 --- a/engine/server/sv_log.c +++ b/engine/server/sv_log.c @@ -73,7 +73,7 @@ void Log_Open( void ) } if( fp ) svs.log.file = fp; - Log_Printf( "Log file started (file \"%s\") (game \"%s\") (version \"%i/%.2f/%d\")\n", + Log_Printf( "Log file started (file \"%s\") (game \"%s\") (version \"%i/%s/%d\")\n", szTestFile, Info_ValueForKey( SV_Serverinfo(), "*gamedir" ), PROTOCOL_VERSION, XASH_VERSION, Q_buildnum() ); } diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index f0e5751b..e0e6e55b 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -739,7 +739,7 @@ void SV_AddToMaster( netadr_t from, sizebuf_t *msg ) Info_SetValueForKey( s, "os", "w", len ); // Windows Info_SetValueForKey( s, "secure", "0", len ); // server anti-cheat Info_SetValueForKey( s, "lan", "0", len ); // LAN servers doesn't send info to master - Info_SetValueForKey( s, "version", va( "%g", XASH_VERSION ), len ); // server region. 255 -- all regions + Info_SetValueForKey( s, "version", va( "%s", XASH_VERSION ), len ); // server region. 255 -- all regions Info_SetValueForKey( s, "region", "255", len ); // server region. 255 -- all regions Info_SetValueForKey( s, "product", GI->gamefolder, len ); // product? Where is the difference with gamedir? @@ -853,7 +853,8 @@ void SV_Init( void ) MSG_Init( &net_message, "NetMessage", net_message_buffer, sizeof( net_message_buffer )); - Q_snprintf( versionString, sizeof( versionString ), "%s: %.2f,%i,%i", "Xash3D", XASH_VERSION, PROTOCOL_VERSION, Q_buildnum() ); + Q_snprintf( versionString, sizeof( versionString ), "%s: %s-%s(%s-%s),%i,%i", + XASH_ENGINE_NAME, XASH_VERSION, Q_buildcommit(), Q_buildos(), Q_buildarch(), PROTOCOL_VERSION, Q_buildnum() ); Cvar_FullSet( "sv_version", versionString, FCVAR_READ_ONLY ); SV_ClearGameState (); // delete all temporary *.hl files