From c068f22329d5cc722622a2183bbb22eef2093df7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 24 Aug 2026 11:16:07 +0200 Subject: initial import --- src/parsec_server/con_ext_sv.cpp | 1193 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 1193 insertions(+) create mode 100755 src/parsec_server/con_ext_sv.cpp (limited to 'src/parsec_server/con_ext_sv.cpp') diff --git a/src/parsec_server/con_ext_sv.cpp b/src/parsec_server/con_ext_sv.cpp new file mode 100755 index 0000000..c3c556d --- /dev/null +++ b/src/parsec_server/con_ext_sv.cpp @@ -0,0 +1,1193 @@ +/* + * PARSEC - Server External Commands + * + * $Author: uberlinuxguy $ - $Date: 2004/09/15 12:25:44 $ + * + * Orginally written by: + * Copyright (c) Clemens Beer 2001 + * Copyright (c) Markus Hadwiger 1996-2001 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// C library +#include +#include +#include +#include +#include + +// compilation flags/debug support +#include "config.h" +#include "debug.h" + +// general definitions +#include "general.h" +#include "objstruc.h" + +// global externals +#include "globals.h" + +// local module header +#include "con_ext_sv.h" + +// proprietary module headers +//#include "con_act.h" +#include "con_aux_sv.h" +#include "con_list_sv.h" +#include "con_main_sv.h" +#include "con_std_sv.h" +#include "con_vald.h" // shared ! +//#include "e_demo.h" +//#include "e_record.h" +//#include "e_replay.h" +#include "sys_file.h" +#include "sys_path.h" + + + +// maximum depth of recursion in command batch files +#define MAX_BATCH_REC_DEPTH 16 + +// special eof needed in package console scripts +#define PACKAGE_CON_EOF ";eof" +#define PACKAGE_CON_EOF_LEN 4 + +// generic string paste area +#define PASTE_STR_LEN 255 +static char paste_str[ PASTE_STR_LEN + 1 ]; + +// string constants +static char con_extension[] = CON_FILE_EXTENSION; +static char invalid_batch_name[]= "invalid name specifier."; +static char recursion_canceled[]= "command canceled due to recursion."; +static char recursion_maxdepth[]= "maximum recursion depth reached."; +static char replaying_script[] = "replay in progress (script)."; +static char replaying_binary[] = "replay in progress (binary)."; +static char no_replay[] = "no replay in progress."; +static char stopped_replay[] = "replay has been stopped."; +static char record_disallowed[] = "recording not allowed (object camera is active)."; + +static char con_file_wldcard1[] = "*" CON_FILE_EXTENSION; +static char con_file_wldcard2[] = REFCON_COMMANDS_DIR "*" CON_FILE_EXTENSION; +static char con_file_wldcard3[] = STDCON_COMMANDS_DIR "*" CON_FILE_EXTENSION; +static char con_file_wldcard4[] = RECORD_COMMANDS_DIR "*" CON_FILE_EXTENSION; + +// name of batch command file to execute on every gameloop start +char gameloop_start_script[ PATH_MAX + 1 ] = ""; + +// list of external commands +char external_commands[ MAX_EXTERNAL_COMMANDS + 1 ][ COMMAND_NAME_ALLOC_LEN + 1 ]; +int external_command_types[ MAX_EXTERNAL_COMMANDS + 1 ]; +int num_external_commands = 0; + +// external batch execution vars +int processing_batch = 0; // flag that commands are called from batch +int idle_reclevel = 0; // level of recursion idle wait stalled execution on +int rec_depth = 0; // current level of recursion + +// action commands not allowed? +int preempt_action_commands = FALSE; + +// batch execution recursive call stack +static int extcom_on_level[ MAX_BATCH_REC_DEPTH + 1 ]; +static FILE *fp_for_level[ MAX_BATCH_REC_DEPTH + 1 ]; + +// log file (created command batch) +FILE *log_fp; +char log_name[ COMMAND_NAME_ALLOC_LEN + 1 ]; +int log_commands = 0; + +// recording file +static char record_name[ COMMAND_NAME_ALLOC_LEN + 1 ]; + +// packet recording/replay file names +char packet_record_name[ COMMAND_NAME_ALLOC_LEN + 1 ]; +char packet_replay_name[ COMMAND_NAME_ALLOC_LEN + 1 ]; + +// single command line +static char com_line[ MAX_CONSOLE_LINE_LENGTH + 1 ]; + +// cat feature variables +static char cat_name[ MAX_CONSOLE_LINE_LENGTH + 1 ]; +static int cat_pos; + +// current active mod name +PUBLIC char* mod_names[ MAX_REGISTERED_MODS ]; +PUBLIC int mod_numnames = 0; +PUBLIC int mod_override = FALSE; + + +// acquire scripts located in mod directories --------------------------------- +// +PRIVATE +void AcquireModScripts() +{ + for ( int mod = 0; mod < mod_numnames; mod++ ) { + + char *path = (char *) ALLOCMEM( strlen( mod_names[ mod ] ) + strlen( con_file_wldcard1 ) + 2 ); + if ( path == NULL ) { + OUTOFMEM( 0 ); + } + + strcpy( path, mod_names[ mod ] ); + strcat( path, "/" ); + strcat( path, con_file_wldcard1 ); + + char *npath = SYSs_ProcessPathString( path ); + SYSs_AcquireScriptPath( npath, COMTYPE_MODIFICATION, mod_names[ mod ] ); + + FREEMEM( path ); + } +} + + +// build list of externally available commands -------------------------------- +// +void BuildExternalCommandList() +{ + //NOTE: + // the sequence of paths scanned in this function mostly determines the + // display order of console scripts (ls command, tab completion, ...). + // the actual precedence of scripts is determined by the search order + // in OpenScript(). for consistency, the two orders should be the same. + + num_external_commands = 0; + + SYS_AcquirePackageScripts( COMTYPE_PACKAGE ); + + if ( mod_override ) { + AcquireModScripts(); + } + + SYSs_AcquireScriptPath( con_file_wldcard1, COMTYPE_ROOT, NULL ); + SYSs_AcquireScriptPath( con_file_wldcard2, COMTYPE_REFERENCE, NULL ); + SYSs_AcquireScriptPath( con_file_wldcard3, COMTYPE_STANDARD, NULL ); + SYSs_AcquireScriptPath( con_file_wldcard4, COMTYPE_RECORDING, NULL ); + + if ( !mod_override ) { + AcquireModScripts(); + } +} + + +// check if string is valid external command ---------------------------------- +// +int CheckExternalCommand( char *com ) +{ + ASSERT( com != NULL ); + + //NOTE: + // command script directories are only scanned once. therefore, + // new commands copied into a directory while the game is still + // running will not be noticed until next startup or explicit + // rescanning via the "rescan" command. + + // to ensure scripts with explicitly specified paths work + com = SYSs_ProcessPathString( com ); + + // scan list in memory (no directory rescanning!!) + int cid = -1; + for ( int eid = 0; eid < num_external_commands; eid++ ) { + ASSERT( external_commands[ eid ] != NULL ); + if ( stricmp( external_commands[ eid ], com ) == 0 ) { + cid = eid; + break; + } + } + + // return command number + 1 (thus 0 means command is invalid) + return ( cid + 1 ); +} + + +// insert command into log file (command batch) ------------------------------- +// +int InsertCommandLog( char *command ) +{ + ASSERT( command != NULL ); + + if ( log_commands && ( strcmp( command, CMSTR( CM_CLOSE ) ) != 0 ) ) { + // append command to currently open logfile + fprintf( log_fp, "%s\n", command ); + return TRUE; + } + + return FALSE; +} + + +// search all console script paths and open batch if it exists ---------------- +// +PRIVATE +FILE *OpenScript( char *script ) +{ + ASSERT( script != NULL ); + + //NOTE: + // the sequence of paths scanned in this function determines the + // precedence of console scripts of the same name but located in + // different directories. + + //NOTE: + // the path search sequence is: + // 1. data package + // 2. root (local) directory + // 3. reference directory (refs) + // 4. standard directory (cons) + // 5. recording directory (recs) + + //NOTE: + // to avoid inconsistencies the search order in E_RECORD::LoadPacket() + // and E_DEMO::DEMO_BinaryOpenDemo() should be consistent + // with the search order used here. + + FILE *fp = NULL; + + strcpy( paste_str, script ); + strcat( paste_str, con_extension ); + + // to ensure scripts with explicitly specified paths work + char *path = SYSs_ProcessPathString( paste_str ); + + if ( SV_PACKAGE_SCRIPTS ) { + + // try to read from package first + if ( ( fp = SYS_fopen( path, "r" ) ) != NULL ) { + return fp; + } + } + + // search root (local) directory + if ( ( fp = fopen( path, "r" ) ) != NULL ) { + return fp; + } + + strcpy( paste_str, REFCON_COMMANDS_DIR ); + strcat( paste_str, script ); + strcat( paste_str, con_extension ); + + // search reference directory (refs) + if ( ( fp = fopen( paste_str, "r" ) ) != NULL ) { + return fp; + } + + strcpy( paste_str, STDCON_COMMANDS_DIR ); + strcat( paste_str, script ); + strcat( paste_str, con_extension ); + + // search standard directory (cons) + if ( ( fp = fopen( paste_str, "r" ) ) != NULL ) { + return fp; + } + + strcpy( paste_str, RECORD_COMMANDS_DIR ); + strcat( paste_str, script ); + strcat( paste_str, con_extension ); + + // search recording directory (recs) + return fopen( paste_str, "r" ); +} + + +// display content of command batch file -------------------------------------- +// +PRIVATE +void CatExternalCommands_ctd() +{ + int i = 0; + + FILE *fp = OpenScript( cat_name ); + + if ( fp != NULL ) { + + SYS_fseek( fp, cat_pos, SEEK_SET ); + + int packeof = 0; + while ( SYS_fgets( com_line, MAX_CONSOLE_LINE_LENGTH, fp ) != NULL ) { + + // check special package eof + if ( strncmp( com_line, PACKAGE_CON_EOF, PACKAGE_CON_EOF_LEN ) == 0 ) { + packeof = 1; + break; + } + + ProcessExternalLine( com_line ); + CON_AddLine( com_line ); + if ( ++i >= cur_vis_conlines - 1 ) { + break; + } + } + + if ( packeof || SYS_feof( fp ) ) { + CON_ListEndPrompt(); + } else { + CON_ListCtdPrompt(); + cat_pos = SYS_ftell( fp ); + } + + SYS_fclose( fp ); + } +} + + +// display content of command batch file (command "cat") ---------------------- +// +int Cmd_CatExternalCommands( char *cstr ) +{ + ASSERT( cstr != NULL ); + HANDLE_COMMAND_DOMAIN_SEP( cstr ); + + char *name = strtok( cstr, " " ); + + if ( ( name == NULL ) || ( strtok( NULL, " " ) != NULL ) ) { + CON_AddLine( "syntax: cat