con_history 1 is not just for clients anymore

This commit is contained in:
myT 2017-10-12 19:12:41 +02:00
parent 741e5e2f12
commit 1f49b43a39
9 changed files with 139 additions and 96 deletions

View file

@ -90,7 +90,7 @@ chg: anti-aliasing sample count is set with r_msaa on all platforms (on Windows,
chg: file system start-up will now verify the presence and integrity of baseq3/pak0-8.pk3 instead of only pak0
add: command history saving with con_history (default: 0)
add: command history saving with con_history (default: 1)
chg: replaced id's Huffman codec code with something both simpler and much faster

View file

@ -310,8 +310,6 @@ void CL_ConInit()
History_Clear( &g_history, g_console_field_width );
Con_ClearNotify();
CL_LoadCommandHistory();
Cmd_RegisterArray( con_cmds, MODULE_CONSOLE );
}

View file

@ -1143,91 +1143,3 @@ void Key_ClearStates()
anykeydown = 0;
}
#define HISTORY_PATH "cnq3cmdhistory"
static const cvar_t* con_history;
void CL_LoadCommandHistory()
{
con_history = Cvar_Get( "con_history", "0", CVAR_ARCHIVE );
Cvar_SetRange( "con_history", CVART_BOOL, NULL, NULL );
Cvar_SetHelp( "con_history", "writes the command history to a file on exit" );
fileHandle_t f;
FS_FOpenFileRead( HISTORY_PATH, &f, qfalse );
if ( f == 0 )
return;
int count;
if ( FS_Read( &count, sizeof(int), f ) != sizeof(int) ||
count <= 0 ||
count > COMMAND_HISTORY ) {
FS_FCloseFile( f );
return;
}
int lengths[COMMAND_HISTORY];
const int lengthBytes = sizeof(int) * count;
if ( FS_Read( lengths, lengthBytes, f ) != lengthBytes ) {
FS_FCloseFile( f );
return;
}
for ( int i = 0; i < count; ++i ) {
const int l = lengths[i];
if ( l <= 0 ||
FS_Read( g_history.commands[i].buffer, l, f ) != l ) {
FS_FCloseFile( f );
return;
}
g_history.commands[i].buffer[l] = '\0';
g_history.commands[i].cursor = l;
}
g_history.next = count;
g_history.display = count;
const int totalCount = ARRAY_LEN( g_history.commands );
for ( int i = count; i < totalCount; ++i ) {
g_history.commands[i].buffer[0] = '\0';
}
FS_FCloseFile(f);
}
void CL_SaveCommandHistory()
{
if ( con_history->integer == 0 )
return;
const fileHandle_t f = FS_FOpenFileWrite( HISTORY_PATH );
if ( f == 0 )
return;
int count = 0;
int lengths[COMMAND_HISTORY];
const int totalCount = ARRAY_LEN( g_history.commands );
for ( int i = 0; i < totalCount; ++i ) {
const char* const s = g_history.commands[(g_history.display + i) % COMMAND_HISTORY].buffer;
if ( *s == '\0' )
continue;
lengths[count++] = strlen( s );
}
FS_Write( &count, sizeof(count), f );
FS_Write( lengths, sizeof(int) * count, f );
for ( int i = 0, j = 0; i < totalCount; ++i ) {
const char* const s = g_history.commands[(g_history.display + i) % COMMAND_HISTORY].buffer;
if ( *s == '\0' )
continue;
FS_Write( s, lengths[j++], f );
}
FS_FCloseFile( f );
}

View file

@ -2103,7 +2103,6 @@ void CL_Shutdown()
CL_ShutdownUI();
CL_SaveCommandHistory();
CL_MapDownload_Cancel();
Cmd_UnregisterModule( MODULE_CLIENT );

View file

@ -39,6 +39,3 @@ qbool Key_GetOverstrikeMode();
void Key_SetOverstrikeMode( qbool state );
void Key_ClearStates();
int Key_GetKey( const char* binding );
void CL_LoadCommandHistory();
void CL_SaveCommandHistory();

View file

@ -80,6 +80,7 @@ cvar_t *com_noErrorInterrupt;
#endif
static cvar_t *com_completionStyle; // 0 = legacy, 1 = ET-style
static cvar_t *con_history;
// com_speeds times
int time_game;
@ -305,6 +306,8 @@ void QDECL Com_Error( int code, const char *fmt, ... )
void Com_Quit( int status )
{
Sys_SaveHistory();
// don't try to shutdown if we are in a recursive error
if ( !com_errorEntered ) {
SV_Shutdown( "Server quit" );
@ -2158,7 +2161,8 @@ static const cvarTableItem_t com_cvars[] =
#if defined(_WIN32) && defined(_DEBUG)
{ &com_noErrorInterrupt, "com_noErrorInterrupt", "0", 0, CVART_BOOL },
#endif
{ &com_completionStyle, "com_completionStyle", "0", CVAR_ARCHIVE, CVART_BOOL, NULL, NULL, help_com_completionStyle }
{ &com_completionStyle, "com_completionStyle", "0", CVAR_ARCHIVE, CVART_BOOL, NULL, NULL, help_com_completionStyle },
{ &con_history, "con_history", "1", CVAR_ARCHIVE, CVART_BOOL, NULL, NULL, "writes the command history to a file on exit" }
};
@ -2265,6 +2269,8 @@ void Com_Init( char *commandLine )
#endif
}
Sys_LoadHistory();
// set com_frameTime so that if a map is started on the
// command line it will still be able to count on com_frameTime
// being random enough for a serverid
@ -3129,6 +3135,92 @@ void History_GetNextCommand( field_t* edit, history_t* history, int width )
edit->widthInChars = width;
}
// It makes no sense for both executables to share the same command history.
#if defined(DEDICATED)
#define HISTORY_PATH "cnq3svcmdhistory"
#else
#define HISTORY_PATH "cnq3cmdhistory"
#endif
void History_LoadFromFile( history_t* history )
{
fileHandle_t f;
FS_FOpenFileRead( HISTORY_PATH, &f, qfalse );
if ( f == 0 )
return;
int count;
if ( FS_Read( &count, sizeof(int), f ) != sizeof(int) ||
count <= 0 ||
count > COMMAND_HISTORY ) {
FS_FCloseFile( f );
return;
}
int lengths[COMMAND_HISTORY];
const int lengthBytes = sizeof(int) * count;
if ( FS_Read( lengths, lengthBytes, f ) != lengthBytes ) {
FS_FCloseFile( f );
return;
}
for ( int i = 0; i < count; ++i ) {
const int l = lengths[i];
if ( l <= 0 ||
FS_Read( history->commands[i].buffer, l, f ) != l ) {
FS_FCloseFile( f );
return;
}
history->commands[i].buffer[l] = '\0';
history->commands[i].cursor = l;
}
history->next = count;
history->display = count;
const int totalCount = ARRAY_LEN( history->commands );
for ( int i = count; i < totalCount; ++i ) {
history->commands[i].buffer[0] = '\0';
}
FS_FCloseFile( f );
}
void History_SaveToFile( const history_t* history )
{
if ( con_history->integer == 0 )
return;
const fileHandle_t f = FS_FOpenFileWrite( HISTORY_PATH );
if ( f == 0 )
return;
int count = 0;
int lengths[COMMAND_HISTORY];
const int totalCount = ARRAY_LEN( history->commands );
for ( int i = 0; i < totalCount; ++i ) {
const char* const s = history->commands[(history->display + i) % COMMAND_HISTORY].buffer;
if ( *s == '\0' )
continue;
lengths[count++] = strlen( s );
}
FS_Write( &count, sizeof(count), f );
FS_Write( lengths, sizeof(int) * count, f );
for ( int i = 0, j = 0; i < totalCount; ++i ) {
const char* const s = history->commands[(history->display + i) % COMMAND_HISTORY].buffer;
if ( *s == '\0' )
continue;
FS_Write( s, lengths[j++], f );
}
FS_FCloseFile( f );
}
const char* Q_itohex( uint64_t number, qbool uppercase, qbool prefix )
{

View file

@ -792,6 +792,8 @@ void History_Clear( history_t* history, int width );
void History_SaveCommand( history_t* history, const field_t* edit );
void History_GetPreviousCommand( field_t* edit, history_t* history );
void History_GetNextCommand( field_t* edit, history_t* history, int width );
void History_LoadFromFile( history_t* history );
void History_SaveToFile( const history_t* history );
/*
==============================================================
@ -1109,6 +1111,9 @@ qbool Sys_HardReboot(); // qtrue when the server can restart itself
qbool Sys_HasCNQ3Parent(); // qtrue if a child of CNQ3
int Sys_GetUptimeSeconds( qbool parent ); // negative if not available
void Sys_LoadHistory();
void Sys_SaveHistory();
// huffman.cpp - id's original code
// used for out-of-band (OOB) datagrams with dynamically created trees
void DynHuff_Compress( msg_t* buf, int offset );

View file

@ -1000,6 +1000,26 @@ int Sys_GetUptimeSeconds( qbool parent )
}
void Sys_LoadHistory()
{
#ifdef DEDICATED
History_LoadFromFile( &tty_history );
#else
History_LoadFromFile( &g_history );
#endif
}
void Sys_SaveHistory()
{
#ifdef DEDICATED
History_SaveToFile( &tty_history );
#else
History_SaveToFile( &g_history );
#endif
}
int main( int argc, char** argv )
{
q_argc = argc;

View file

@ -664,3 +664,23 @@ void Sys_SetErrorText( const char *buf )
s_wcd.hwndInputLine = NULL;
}
}
void Sys_LoadHistory()
{
#ifdef DEDICATED
History_LoadFromFile( &s_wcd.history );
#else
History_LoadFromFile( &g_history );
#endif
}
void Sys_SaveHistory()
{
#ifdef DEDICATED
History_SaveToFile( &s_wcd.history );
#else
History_SaveToFile( &g_history );
#endif
}