mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-29 15:51:45 +00:00
Spalte cmd.c in Eintzeldateien
This commit is contained in:
parent
4cc6b8103d
commit
88c511f270
5 changed files with 475 additions and 373 deletions
24
Makefile
24
Makefile
|
@ -195,7 +195,9 @@ CLIENT_OBJS = \
|
||||||
|
|
||||||
# Common objects
|
# Common objects
|
||||||
COMMON_OBJS = \
|
COMMON_OBJS = \
|
||||||
build/common/cmd.o \
|
build/common/co_cmdexecution.o \
|
||||||
|
build/common/co_cmdparser.o \
|
||||||
|
build/common/co_cmdscript.o \
|
||||||
build/common/cmodel.o \
|
build/common/cmodel.o \
|
||||||
build/common/common.o \
|
build/common/common.o \
|
||||||
build/common/crc.o \
|
build/common/crc.o \
|
||||||
|
@ -267,7 +269,9 @@ DEDICATED_SERVER_OBJS = \
|
||||||
|
|
||||||
# Dedicated server common objects
|
# Dedicated server common objects
|
||||||
DEDICATED_SERVER_COMMON_OBJS = \
|
DEDICATED_SERVER_COMMON_OBJS = \
|
||||||
build/dedicated_server_common/cmd.o \
|
build/dedicated_server_common/co_cmdexecution.o \
|
||||||
|
build/dedicated_server_common/co_cmdparser.o \
|
||||||
|
build/dedicated_server_common/co_cmdscript.o \
|
||||||
build/dedicated_server_common/cmodel.o \
|
build/dedicated_server_common/cmodel.o \
|
||||||
build/dedicated_server_common/common.o \
|
build/dedicated_server_common/common.o \
|
||||||
build/dedicated_server_common/crc.o \
|
build/dedicated_server_common/crc.o \
|
||||||
|
@ -478,9 +482,15 @@ build/client/sound/snd_wav.o : src/client/sound/snd_wav.c
|
||||||
# ---------
|
# ---------
|
||||||
|
|
||||||
# Common build
|
# Common build
|
||||||
build/common/cmd.o : src/common/cmd.c
|
build/common/co_cmdexecution.o : src/common/co_cmdexecution.c
|
||||||
$(CC) $(CFLAGS_CLIENT) -o $@ -c $<
|
$(CC) $(CFLAGS_CLIENT) -o $@ -c $<
|
||||||
|
|
||||||
|
build/common/co_cmdparser.o : src/common/co_cmdparser.c
|
||||||
|
$(CC) $(CFLAGS_CLIENT) -o $@ -c $<
|
||||||
|
|
||||||
|
build/common/co_cmdscript.o : src/common/co_cmdscript.c
|
||||||
|
$(CC) $(CFLAGS_CLIENT) -o $@ -c $<
|
||||||
|
|
||||||
build/common/cmodel.o : src/common/cmodel.c
|
build/common/cmodel.o : src/common/cmodel.c
|
||||||
$(CC) $(CFLAGS_CLIENT) -o $@ -c $<
|
$(CC) $(CFLAGS_CLIENT) -o $@ -c $<
|
||||||
|
|
||||||
|
@ -608,9 +618,15 @@ build/dedicated_server/sv_world.o : src/server/sv_world.c
|
||||||
# ---------
|
# ---------
|
||||||
|
|
||||||
# Dedicated server common build
|
# Dedicated server common build
|
||||||
build/dedicated_server_common/cmd.o : src/common/cmd.c
|
build/dedicated_server_common/co_cmdexecution.o : src/common/co_cmdexecution.c
|
||||||
|
$(CC) $(CFLAGS_DEDICATED_SERVER) -o $@ -c $<
|
||||||
|
|
||||||
|
build/dedicated_server_common/co_cmdparser.o : src/common/co_cmdparser.c
|
||||||
$(CC) $(CFLAGS_DEDICATED_SERVER) -o $@ -c $<
|
$(CC) $(CFLAGS_DEDICATED_SERVER) -o $@ -c $<
|
||||||
|
|
||||||
|
build/dedicated_server_common/co_cmdscript.o : src/common/co_cmdscript.c
|
||||||
|
$(CC) $(CFLAGS_DEDICATED_SERVER) -o $@ -c $<
|
||||||
|
|
||||||
build/dedicated_server_common/cmodel.o : src/common/cmodel.c
|
build/dedicated_server_common/cmodel.o : src/common/cmodel.c
|
||||||
$(CC) $(CFLAGS_DEDICATED_SERVER) -o $@ -c $<
|
$(CC) $(CFLAGS_DEDICATED_SERVER) -o $@ -c $<
|
||||||
|
|
||||||
|
|
|
@ -19,378 +19,14 @@
|
||||||
*
|
*
|
||||||
* =======================================================================
|
* =======================================================================
|
||||||
*
|
*
|
||||||
* This file implements the command processor. Every command which is
|
* This file implements the command execution, e.g. directs the commands
|
||||||
* send vie the command line at startup, via the console and via rcon is
|
* to the appropriate subsystems.
|
||||||
* processed here and send to the apropriate subsystem.
|
|
||||||
*
|
*
|
||||||
* =======================================================================
|
* =======================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qcommon.h"
|
#include "qcommon.h"
|
||||||
|
#include "header/cmd.h"
|
||||||
void Cmd_ForwardToServer (void);
|
|
||||||
|
|
||||||
#define MAX_ALIAS_NAME 32
|
|
||||||
|
|
||||||
typedef struct cmdalias_s {
|
|
||||||
struct cmdalias_s *next;
|
|
||||||
char name[MAX_ALIAS_NAME];
|
|
||||||
char *value;
|
|
||||||
} cmdalias_t;
|
|
||||||
|
|
||||||
cmdalias_t *cmd_alias;
|
|
||||||
|
|
||||||
qboolean cmd_wait;
|
|
||||||
|
|
||||||
#define ALIAS_LOOP_COUNT 16
|
|
||||||
int alias_count; /* for detecting runaway loops */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Causes execution of the remainder of the command buffer to be delayed
|
|
||||||
* until next frame. This allows commands like: bind g "impulse 5 ;
|
|
||||||
* +attack ; wait ; -attack ; impulse 2"
|
|
||||||
*/
|
|
||||||
void Cmd_Wait_f (void) {
|
|
||||||
cmd_wait = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* COMMAND BUFFER */
|
|
||||||
|
|
||||||
sizebuf_t cmd_text;
|
|
||||||
byte cmd_text_buf[8192];
|
|
||||||
|
|
||||||
char defer_text_buf[8192];
|
|
||||||
|
|
||||||
void Cbuf_Init (void) {
|
|
||||||
SZ_Init (&cmd_text, cmd_text_buf, sizeof(cmd_text_buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Adds command text at the end of the buffer
|
|
||||||
*/
|
|
||||||
void Cbuf_AddText (char *text) {
|
|
||||||
int l;
|
|
||||||
|
|
||||||
l = strlen (text);
|
|
||||||
|
|
||||||
if (cmd_text.cursize + l >= cmd_text.maxsize) {
|
|
||||||
Com_Printf ("Cbuf_AddText: overflow\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SZ_Write (&cmd_text, text, strlen (text));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Adds command text immediately after the current command
|
|
||||||
* Adds a \n to the text
|
|
||||||
*/
|
|
||||||
void Cbuf_InsertText (char *text) {
|
|
||||||
char *temp;
|
|
||||||
int templen;
|
|
||||||
|
|
||||||
/* copy off any commands still remaining in the exec buffer */
|
|
||||||
templen = cmd_text.cursize;
|
|
||||||
|
|
||||||
if (templen) {
|
|
||||||
temp = Z_Malloc (templen);
|
|
||||||
memcpy (temp, cmd_text.data, templen);
|
|
||||||
SZ_Clear (&cmd_text);
|
|
||||||
|
|
||||||
} else
|
|
||||||
temp = NULL;
|
|
||||||
|
|
||||||
/* add the entire text of the file */
|
|
||||||
Cbuf_AddText (text);
|
|
||||||
|
|
||||||
/* add the copied off data */
|
|
||||||
if (templen) {
|
|
||||||
SZ_Write (&cmd_text, temp, templen);
|
|
||||||
Z_Free (temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cbuf_CopyToDefer (void) {
|
|
||||||
memcpy(defer_text_buf, cmd_text_buf, cmd_text.cursize);
|
|
||||||
defer_text_buf[cmd_text.cursize] = 0;
|
|
||||||
cmd_text.cursize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cbuf_InsertFromDefer (void) {
|
|
||||||
Cbuf_InsertText (defer_text_buf);
|
|
||||||
defer_text_buf[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cbuf_ExecuteText (int exec_when, char *text) {
|
|
||||||
switch (exec_when) {
|
|
||||||
case EXEC_NOW:
|
|
||||||
Cmd_ExecuteString (text);
|
|
||||||
break;
|
|
||||||
case EXEC_INSERT:
|
|
||||||
Cbuf_InsertText (text);
|
|
||||||
break;
|
|
||||||
case EXEC_APPEND:
|
|
||||||
Cbuf_AddText (text);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Com_Error (ERR_FATAL, "Cbuf_ExecuteText: bad exec_when");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cbuf_Execute (void) {
|
|
||||||
int i;
|
|
||||||
char *text;
|
|
||||||
char line[1024];
|
|
||||||
int quotes;
|
|
||||||
|
|
||||||
alias_count = 0; /* don't allow infinite alias loops */
|
|
||||||
|
|
||||||
while (cmd_text.cursize) {
|
|
||||||
/* find a \n or ; line break */
|
|
||||||
text = (char *)cmd_text.data;
|
|
||||||
|
|
||||||
quotes = 0;
|
|
||||||
|
|
||||||
for (i=0 ; i< cmd_text.cursize ; i++) {
|
|
||||||
if (text[i] == '"')
|
|
||||||
quotes++;
|
|
||||||
|
|
||||||
if ( !(quotes&1) && text[i] == ';')
|
|
||||||
break; /* don't break if inside a quoted string */
|
|
||||||
|
|
||||||
if (text[i] == '\n')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
memcpy (line, text, i);
|
|
||||||
line[i] = 0;
|
|
||||||
|
|
||||||
/* delete the text from the command buffer and move remaining
|
|
||||||
commands down this is necessary because commands (exec,
|
|
||||||
alias) can insert data at the beginning of the text buffer */
|
|
||||||
if (i == cmd_text.cursize)
|
|
||||||
cmd_text.cursize = 0;
|
|
||||||
|
|
||||||
else {
|
|
||||||
i++;
|
|
||||||
cmd_text.cursize -= i;
|
|
||||||
memmove (text, text+i, cmd_text.cursize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* execute the command line */
|
|
||||||
Cmd_ExecuteString (line);
|
|
||||||
|
|
||||||
if (cmd_wait) {
|
|
||||||
/* skip out while text still remains in buffer,
|
|
||||||
leaving it for next frame */
|
|
||||||
cmd_wait = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Adds command line parameters as script statements Commands lead with
|
|
||||||
* a +, and continue until another +
|
|
||||||
*
|
|
||||||
* Set commands are added early, so they are guaranteed to be set before
|
|
||||||
* the client and server initialize for the first time.
|
|
||||||
*
|
|
||||||
* Other commands are added late, after all initialization is complete.
|
|
||||||
*/
|
|
||||||
void Cbuf_AddEarlyCommands (qboolean clear) {
|
|
||||||
int i;
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
for (i=0 ; i<COM_Argc() ; i++) {
|
|
||||||
s = COM_Argv(i);
|
|
||||||
|
|
||||||
if (strcmp (s, "+set"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Cbuf_AddText (va("set %s %s\n", COM_Argv(i+1), COM_Argv(i+2)));
|
|
||||||
|
|
||||||
if (clear) {
|
|
||||||
COM_ClearArgv(i);
|
|
||||||
COM_ClearArgv(i+1);
|
|
||||||
COM_ClearArgv(i+2);
|
|
||||||
}
|
|
||||||
|
|
||||||
i+=2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Adds command line parameters as script statements
|
|
||||||
* Commands lead with a + and continue until another + or -
|
|
||||||
* quake +vid_ref gl +map amlev1
|
|
||||||
*
|
|
||||||
* Returns true if any late commands were added, which
|
|
||||||
* will keep the demoloop from immediately starting
|
|
||||||
*/
|
|
||||||
qboolean Cbuf_AddLateCommands (void) {
|
|
||||||
int i, j;
|
|
||||||
int s;
|
|
||||||
char *text, *build, c;
|
|
||||||
int argc;
|
|
||||||
qboolean ret;
|
|
||||||
|
|
||||||
/* build the combined string to parse from */
|
|
||||||
s = 0;
|
|
||||||
argc = COM_Argc();
|
|
||||||
|
|
||||||
for (i=1 ; i<argc ; i++) {
|
|
||||||
s += strlen (COM_Argv(i)) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!s)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
text = Z_Malloc (s+1);
|
|
||||||
text[0] = 0;
|
|
||||||
|
|
||||||
for (i=1 ; i<argc ; i++) {
|
|
||||||
strcat (text,COM_Argv(i));
|
|
||||||
|
|
||||||
if (i != argc-1)
|
|
||||||
strcat (text, " ");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pull out the commands */
|
|
||||||
build = Z_Malloc (s+1);
|
|
||||||
build[0] = 0;
|
|
||||||
|
|
||||||
for (i=0 ; i<s-1 ; i++) {
|
|
||||||
if (text[i] == '+') {
|
|
||||||
i++;
|
|
||||||
|
|
||||||
for (j=i ; (text[j] != '+') && (text[j] != '-') && (text[j] != 0) ; j++)
|
|
||||||
;
|
|
||||||
|
|
||||||
c = text[j];
|
|
||||||
text[j] = 0;
|
|
||||||
|
|
||||||
strcat (build, text+i);
|
|
||||||
strcat (build, "\n");
|
|
||||||
text[j] = c;
|
|
||||||
i = j-1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = (build[0] != 0);
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
Cbuf_AddText (build);
|
|
||||||
|
|
||||||
Z_Free (text);
|
|
||||||
Z_Free (build);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* SCRIPT COMMANDS */
|
|
||||||
|
|
||||||
void Cmd_Exec_f (void) {
|
|
||||||
char *f, *f2;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
if (Cmd_Argc () != 2) {
|
|
||||||
Com_Printf ("exec <filename> : execute a script file\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = FS_LoadFile (Cmd_Argv(1), (void **)&f);
|
|
||||||
|
|
||||||
if (!f) {
|
|
||||||
Com_Printf ("couldn't exec %s\n",Cmd_Argv(1));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Com_Printf ("execing %s\n",Cmd_Argv(1));
|
|
||||||
|
|
||||||
/* the file doesn't have a trailing 0, so we need to copy it off */
|
|
||||||
f2 = Z_Malloc(len+1);
|
|
||||||
memcpy (f2, f, len);
|
|
||||||
f2[len] = 0;
|
|
||||||
|
|
||||||
Cbuf_InsertText (f2);
|
|
||||||
|
|
||||||
Z_Free (f2);
|
|
||||||
FS_FreeFile (f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Just prints the rest of the line to the console
|
|
||||||
*/
|
|
||||||
void Cmd_Echo_f (void) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=1 ; i<Cmd_Argc() ; i++)
|
|
||||||
Com_Printf ("%s ",Cmd_Argv(i));
|
|
||||||
|
|
||||||
Com_Printf ("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Creates a new command that executes
|
|
||||||
* a command string (possibly ; seperated)
|
|
||||||
*/
|
|
||||||
void Cmd_Alias_f (void) {
|
|
||||||
cmdalias_t *a;
|
|
||||||
char cmd[1024];
|
|
||||||
int i, c;
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
if (Cmd_Argc() == 1) {
|
|
||||||
Com_Printf ("Current alias commands:\n");
|
|
||||||
|
|
||||||
for (a = cmd_alias ; a ; a=a->next)
|
|
||||||
Com_Printf ("%s : %s\n", a->name, a->value);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
s = Cmd_Argv(1);
|
|
||||||
|
|
||||||
if (strlen(s) >= MAX_ALIAS_NAME) {
|
|
||||||
Com_Printf ("Alias name is too long\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if the alias already exists, reuse it */
|
|
||||||
for (a = cmd_alias ; a ; a=a->next) {
|
|
||||||
if (!strcmp(s, a->name)) {
|
|
||||||
Z_Free (a->value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!a) {
|
|
||||||
a = Z_Malloc (sizeof(cmdalias_t));
|
|
||||||
a->next = cmd_alias;
|
|
||||||
cmd_alias = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy (a->name, s);
|
|
||||||
|
|
||||||
/* copy the rest of the command line */
|
|
||||||
cmd[0] = 0; /* start out with a null string */
|
|
||||||
c = Cmd_Argc();
|
|
||||||
|
|
||||||
for (i=2 ; i< c ; i++) {
|
|
||||||
strcat (cmd, Cmd_Argv(i));
|
|
||||||
|
|
||||||
if (i != (c - 1))
|
|
||||||
strcat (cmd, " ");
|
|
||||||
}
|
|
||||||
|
|
||||||
strcat (cmd, "\n");
|
|
||||||
|
|
||||||
a->value = CopyString (cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* COMMAND EXECUTION */
|
|
||||||
|
|
||||||
typedef struct cmd_function_s {
|
typedef struct cmd_function_s {
|
||||||
struct cmd_function_s *next;
|
struct cmd_function_s *next;
|
||||||
|
@ -398,7 +34,7 @@ typedef struct cmd_function_s {
|
||||||
xcommand_t function;
|
xcommand_t function;
|
||||||
} cmd_function_t;
|
} cmd_function_t;
|
||||||
|
|
||||||
static int cmd_argc;
|
static int cmd_argc;
|
||||||
static char *cmd_argv[MAX_STRING_TOKENS];
|
static char *cmd_argv[MAX_STRING_TOKENS];
|
||||||
static char *cmd_null_string = "";
|
static char *cmd_null_string = "";
|
||||||
static char cmd_args[MAX_STRING_CHARS];
|
static char cmd_args[MAX_STRING_CHARS];
|
||||||
|
@ -718,3 +354,4 @@ void Cmd_Init (void) {
|
||||||
Cmd_AddCommand ("alias",Cmd_Alias_f);
|
Cmd_AddCommand ("alias",Cmd_Alias_f);
|
||||||
Cmd_AddCommand ("wait", Cmd_Wait_f);
|
Cmd_AddCommand ("wait", Cmd_Wait_f);
|
||||||
}
|
}
|
||||||
|
|
276
src/common/co_cmdparser.c
Normal file
276
src/common/co_cmdparser.c
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* =======================================================================
|
||||||
|
*
|
||||||
|
* This file implements the main part of the command processor. Every
|
||||||
|
* command which is send vie the command line at startup, via the
|
||||||
|
* console and via rcon is processed here and send to the apropriate
|
||||||
|
* subsystem.
|
||||||
|
*
|
||||||
|
* =======================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qcommon.h"
|
||||||
|
#include "header/cmd.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Causes execution of the remainder of the command buffer to be delayed
|
||||||
|
* until next frame. This allows commands like: bind g "impulse 5 ;
|
||||||
|
* +attack ; wait ; -attack ; impulse 2"
|
||||||
|
*/
|
||||||
|
void Cmd_Wait_f (void) {
|
||||||
|
cmd_wait = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* COMMAND BUFFER */
|
||||||
|
|
||||||
|
sizebuf_t cmd_text;
|
||||||
|
byte cmd_text_buf[8192];
|
||||||
|
|
||||||
|
char defer_text_buf[8192];
|
||||||
|
|
||||||
|
void Cbuf_Init (void) {
|
||||||
|
SZ_Init (&cmd_text, cmd_text_buf, sizeof(cmd_text_buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds command text at the end of the buffer
|
||||||
|
*/
|
||||||
|
void Cbuf_AddText (char *text) {
|
||||||
|
int l;
|
||||||
|
|
||||||
|
l = strlen (text);
|
||||||
|
|
||||||
|
if (cmd_text.cursize + l >= cmd_text.maxsize) {
|
||||||
|
Com_Printf ("Cbuf_AddText: overflow\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SZ_Write (&cmd_text, text, strlen (text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds command text immediately after the current command
|
||||||
|
* Adds a \n to the text
|
||||||
|
*/
|
||||||
|
void Cbuf_InsertText (char *text) {
|
||||||
|
char *temp;
|
||||||
|
int templen;
|
||||||
|
|
||||||
|
/* copy off any commands still remaining in the exec buffer */
|
||||||
|
templen = cmd_text.cursize;
|
||||||
|
|
||||||
|
if (templen) {
|
||||||
|
temp = Z_Malloc (templen);
|
||||||
|
memcpy (temp, cmd_text.data, templen);
|
||||||
|
SZ_Clear (&cmd_text);
|
||||||
|
|
||||||
|
} else
|
||||||
|
temp = NULL;
|
||||||
|
|
||||||
|
/* add the entire text of the file */
|
||||||
|
Cbuf_AddText (text);
|
||||||
|
|
||||||
|
/* add the copied off data */
|
||||||
|
if (templen) {
|
||||||
|
SZ_Write (&cmd_text, temp, templen);
|
||||||
|
Z_Free (temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cbuf_CopyToDefer (void) {
|
||||||
|
memcpy(defer_text_buf, cmd_text_buf, cmd_text.cursize);
|
||||||
|
defer_text_buf[cmd_text.cursize] = 0;
|
||||||
|
cmd_text.cursize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cbuf_InsertFromDefer (void) {
|
||||||
|
Cbuf_InsertText (defer_text_buf);
|
||||||
|
defer_text_buf[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cbuf_ExecuteText (int exec_when, char *text) {
|
||||||
|
switch (exec_when) {
|
||||||
|
case EXEC_NOW:
|
||||||
|
Cmd_ExecuteString (text);
|
||||||
|
break;
|
||||||
|
case EXEC_INSERT:
|
||||||
|
Cbuf_InsertText (text);
|
||||||
|
break;
|
||||||
|
case EXEC_APPEND:
|
||||||
|
Cbuf_AddText (text);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Com_Error (ERR_FATAL, "Cbuf_ExecuteText: bad exec_when");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cbuf_Execute (void) {
|
||||||
|
int i;
|
||||||
|
char *text;
|
||||||
|
char line[1024];
|
||||||
|
int quotes;
|
||||||
|
|
||||||
|
alias_count = 0; /* don't allow infinite alias loops */
|
||||||
|
|
||||||
|
while (cmd_text.cursize) {
|
||||||
|
/* find a \n or ; line break */
|
||||||
|
text = (char *)cmd_text.data;
|
||||||
|
|
||||||
|
quotes = 0;
|
||||||
|
|
||||||
|
for (i=0 ; i< cmd_text.cursize ; i++) {
|
||||||
|
if (text[i] == '"')
|
||||||
|
quotes++;
|
||||||
|
|
||||||
|
if ( !(quotes&1) && text[i] == ';')
|
||||||
|
break; /* don't break if inside a quoted string */
|
||||||
|
|
||||||
|
if (text[i] == '\n')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
memcpy (line, text, i);
|
||||||
|
line[i] = 0;
|
||||||
|
|
||||||
|
/* delete the text from the command buffer and move remaining
|
||||||
|
commands down this is necessary because commands (exec,
|
||||||
|
alias) can insert data at the beginning of the text buffer */
|
||||||
|
if (i == cmd_text.cursize)
|
||||||
|
cmd_text.cursize = 0;
|
||||||
|
|
||||||
|
else {
|
||||||
|
i++;
|
||||||
|
cmd_text.cursize -= i;
|
||||||
|
memmove (text, text+i, cmd_text.cursize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* execute the command line */
|
||||||
|
Cmd_ExecuteString (line);
|
||||||
|
|
||||||
|
if (cmd_wait) {
|
||||||
|
/* skip out while text still remains in buffer,
|
||||||
|
leaving it for next frame */
|
||||||
|
cmd_wait = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds command line parameters as script statements Commands lead with
|
||||||
|
* a +, and continue until another +
|
||||||
|
*
|
||||||
|
* Set commands are added early, so they are guaranteed to be set before
|
||||||
|
* the client and server initialize for the first time.
|
||||||
|
*
|
||||||
|
* Other commands are added late, after all initialization is complete.
|
||||||
|
*/
|
||||||
|
void Cbuf_AddEarlyCommands (qboolean clear) {
|
||||||
|
int i;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
for (i=0 ; i<COM_Argc() ; i++) {
|
||||||
|
s = COM_Argv(i);
|
||||||
|
|
||||||
|
if (strcmp (s, "+set"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Cbuf_AddText (va("set %s %s\n", COM_Argv(i+1), COM_Argv(i+2)));
|
||||||
|
|
||||||
|
if (clear) {
|
||||||
|
COM_ClearArgv(i);
|
||||||
|
COM_ClearArgv(i+1);
|
||||||
|
COM_ClearArgv(i+2);
|
||||||
|
}
|
||||||
|
|
||||||
|
i+=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds command line parameters as script statements
|
||||||
|
* Commands lead with a + and continue until another + or -
|
||||||
|
* quake +vid_ref gl +map amlev1
|
||||||
|
*
|
||||||
|
* Returns true if any late commands were added, which
|
||||||
|
* will keep the demoloop from immediately starting
|
||||||
|
*/
|
||||||
|
qboolean Cbuf_AddLateCommands (void) {
|
||||||
|
int i, j;
|
||||||
|
int s;
|
||||||
|
char *text, *build, c;
|
||||||
|
int argc;
|
||||||
|
qboolean ret;
|
||||||
|
|
||||||
|
/* build the combined string to parse from */
|
||||||
|
s = 0;
|
||||||
|
argc = COM_Argc();
|
||||||
|
|
||||||
|
for (i=1 ; i<argc ; i++) {
|
||||||
|
s += strlen (COM_Argv(i)) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!s)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
text = Z_Malloc (s+1);
|
||||||
|
text[0] = 0;
|
||||||
|
|
||||||
|
for (i=1 ; i<argc ; i++) {
|
||||||
|
strcat (text,COM_Argv(i));
|
||||||
|
|
||||||
|
if (i != argc-1)
|
||||||
|
strcat (text, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pull out the commands */
|
||||||
|
build = Z_Malloc (s+1);
|
||||||
|
build[0] = 0;
|
||||||
|
|
||||||
|
for (i=0 ; i<s-1 ; i++) {
|
||||||
|
if (text[i] == '+') {
|
||||||
|
i++;
|
||||||
|
|
||||||
|
for (j=i ; (text[j] != '+') && (text[j] != '-') && (text[j] != 0) ; j++)
|
||||||
|
;
|
||||||
|
|
||||||
|
c = text[j];
|
||||||
|
text[j] = 0;
|
||||||
|
|
||||||
|
strcat (build, text+i);
|
||||||
|
strcat (build, "\n");
|
||||||
|
text[j] = c;
|
||||||
|
i = j-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = (build[0] != 0);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
Cbuf_AddText (build);
|
||||||
|
|
||||||
|
Z_Free (text);
|
||||||
|
Z_Free (build);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
128
src/common/co_cmdscript.c
Normal file
128
src/common/co_cmdscript.c
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* =======================================================================
|
||||||
|
*
|
||||||
|
* This file implements the command processor for command scripting.
|
||||||
|
*
|
||||||
|
* =======================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qcommon.h"
|
||||||
|
#include "header/cmd.h"
|
||||||
|
|
||||||
|
void Cmd_Exec_f (void) {
|
||||||
|
char *f, *f2;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (Cmd_Argc () != 2) {
|
||||||
|
Com_Printf ("exec <filename> : execute a script file\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = FS_LoadFile (Cmd_Argv(1), (void **)&f);
|
||||||
|
|
||||||
|
if (!f) {
|
||||||
|
Com_Printf ("couldn't exec %s\n",Cmd_Argv(1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Com_Printf ("execing %s\n",Cmd_Argv(1));
|
||||||
|
|
||||||
|
/* the file doesn't have a trailing 0, so we need to copy it off */
|
||||||
|
f2 = Z_Malloc(len+1);
|
||||||
|
memcpy (f2, f, len);
|
||||||
|
f2[len] = 0;
|
||||||
|
|
||||||
|
Cbuf_InsertText (f2);
|
||||||
|
|
||||||
|
Z_Free (f2);
|
||||||
|
FS_FreeFile (f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Just prints the rest of the line to the console
|
||||||
|
*/
|
||||||
|
void Cmd_Echo_f (void) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=1 ; i<Cmd_Argc() ; i++)
|
||||||
|
Com_Printf ("%s ",Cmd_Argv(i));
|
||||||
|
|
||||||
|
Com_Printf ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates a new command that executes
|
||||||
|
* a command string (possibly ; seperated)
|
||||||
|
*/
|
||||||
|
void Cmd_Alias_f (void) {
|
||||||
|
cmdalias_t *a;
|
||||||
|
char cmd[1024];
|
||||||
|
int i, c;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
if (Cmd_Argc() == 1) {
|
||||||
|
Com_Printf ("Current alias commands:\n");
|
||||||
|
|
||||||
|
for (a = cmd_alias ; a ; a=a->next)
|
||||||
|
Com_Printf ("%s : %s\n", a->name, a->value);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = Cmd_Argv(1);
|
||||||
|
|
||||||
|
if (strlen(s) >= MAX_ALIAS_NAME) {
|
||||||
|
Com_Printf ("Alias name is too long\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if the alias already exists, reuse it */
|
||||||
|
for (a = cmd_alias ; a ; a=a->next) {
|
||||||
|
if (!strcmp(s, a->name)) {
|
||||||
|
Z_Free (a->value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!a) {
|
||||||
|
a = Z_Malloc (sizeof(cmdalias_t));
|
||||||
|
a->next = cmd_alias;
|
||||||
|
cmd_alias = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy (a->name, s);
|
||||||
|
|
||||||
|
/* copy the rest of the command line */
|
||||||
|
cmd[0] = 0; /* start out with a null string */
|
||||||
|
c = Cmd_Argc();
|
||||||
|
|
||||||
|
for (i=2 ; i< c ; i++) {
|
||||||
|
strcat (cmd, Cmd_Argv(i));
|
||||||
|
|
||||||
|
if (i != (c - 1))
|
||||||
|
strcat (cmd, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat (cmd, "\n");
|
||||||
|
|
||||||
|
a->value = CopyString (cmd);
|
||||||
|
}
|
||||||
|
|
45
src/common/header/cmd.h
Normal file
45
src/common/header/cmd.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* =======================================================================
|
||||||
|
*
|
||||||
|
* The header for the command processor system
|
||||||
|
*
|
||||||
|
* =======================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MAX_ALIAS_NAME 32
|
||||||
|
#define ALIAS_LOOP_COUNT 16
|
||||||
|
|
||||||
|
typedef struct cmdalias_s {
|
||||||
|
struct cmdalias_s *next;
|
||||||
|
char name[MAX_ALIAS_NAME];
|
||||||
|
char *value;
|
||||||
|
} cmdalias_t;
|
||||||
|
|
||||||
|
cmdalias_t *cmd_alias;
|
||||||
|
qboolean cmd_wait;
|
||||||
|
|
||||||
|
int alias_count; /* for detecting runaway loops */
|
||||||
|
|
||||||
|
void Cmd_Exec_f (void);
|
||||||
|
void Cmd_Echo_f (void);
|
||||||
|
void Cmd_Alias_f (void);
|
||||||
|
void Cmd_Wait_f (void);
|
||||||
|
|
Loading…
Reference in a new issue