mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Implemented variable substitution and did various cleanups to the parser.
Changed Cmd_TokenizeString to accept a flag that controls the application of filters (tags, variables, escape characters) to the tokens and modified a few places in the source that called it. Added a secondary command buffer that is parsed without filters for legacy command support. Currently, it is only used for commands stuffed into the console from the server. It is hacky, and I hope to eventually generalize the console interface to support any number of buffers and audit the rest of the code to recognize it. For now, the legacy buffer at least keeps escape character parsing from destroying info strings.
This commit is contained in:
parent
f78ec56975
commit
8d124f9c2b
6 changed files with 254 additions and 168 deletions
|
@ -29,7 +29,9 @@
|
|||
#ifndef __cmd_h
|
||||
#define __cmd_h
|
||||
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
#include "QF/dstring.h"
|
||||
|
||||
//===========================================================================
|
||||
|
||||
|
@ -45,9 +47,11 @@ The game starts with a Cbuf_AddText ("exec quake.rc\n"); Cbuf_Execute ();
|
|||
|
||||
*/
|
||||
|
||||
|
||||
void Cbuf_Init (void);
|
||||
// allocates an initial text buffer that will grow as needed
|
||||
|
||||
void Cbuf_AddTextTo (dstring_t *buffer, const char *text);
|
||||
void Cbuf_AddText (const char *text);
|
||||
// as new commands are generated from the console or keybindings,
|
||||
// the text is added to the end of the command buffer.
|
||||
|
@ -126,7 +130,7 @@ int Cmd_CheckParm (const char *parm);
|
|||
// Returns the position (1 to argc-1) in the command's argument list
|
||||
// where the given parameter apears, or 0 if not present
|
||||
|
||||
void Cmd_TokenizeString (const char *text);
|
||||
void Cmd_TokenizeString (const char *text, qboolean filter);
|
||||
// Takes a null terminated string. Does not need to be /n terminated.
|
||||
// breaks the string up into arg tokens.
|
||||
|
||||
|
@ -147,8 +151,8 @@ void Cmd_Exec_File (const char *path);
|
|||
extern char *com_token;
|
||||
const char *COM_Parse (const char *data);
|
||||
|
||||
void Cmd_ParseSpecial (char *s);
|
||||
|
||||
extern struct cvar_s *cmd_warncmd;
|
||||
|
||||
extern dstring_t *cmd_legacybuffer; // Allow access to the legacy buffer as an alternate console buffer
|
||||
|
||||
#endif // __cmd_h
|
||||
|
|
|
@ -1,3 +1,34 @@
|
|||
/*
|
||||
dstring.h
|
||||
|
||||
Dynamic string buffer functions
|
||||
|
||||
Copyright (C) 1996-1997 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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef __dstring_h
|
||||
#define __dstring_h
|
||||
|
||||
typedef struct dstring_s {
|
||||
unsigned long int size, truesize;
|
||||
char *str;
|
||||
|
@ -18,3 +49,4 @@ dstring_t *dstring_newstr (void);
|
|||
void dstring_appendstr (dstring_t *dstr, const char *str);
|
||||
void dstring_insertstr (dstring_t *dstr, const char *str, unsigned int pos);
|
||||
void dstring_clearstr (dstring_t *dstr);
|
||||
#endif // __dstring_h
|
||||
|
|
371
libs/util/cmd.c
371
libs/util/cmd.c
|
@ -59,9 +59,9 @@ typedef struct cmdalias_s {
|
|||
|
||||
cmdalias_t *cmd_alias;
|
||||
cmd_source_t cmd_source;
|
||||
dstring_t *cmd_buffer;
|
||||
dstring_t *cmd_argbuf;
|
||||
dstring_t *cmd_buffer, *cmd_legacybuffer, *cmd_activebuffer, *cmd_argbuf;
|
||||
qboolean cmd_wait = false;
|
||||
qboolean cmd_legacy = false;
|
||||
int cmd_argc;
|
||||
int cmd_maxargc = 0;
|
||||
dstring_t **cmd_argv = 0;
|
||||
|
@ -96,26 +96,69 @@ Cmd_Wait_f (void)
|
|||
|
||||
byte cmd_text_buf[8192];
|
||||
|
||||
void Cbuf_Init (void) {
|
||||
void
|
||||
Cbuf_Init (void)
|
||||
{
|
||||
|
||||
cmd_buffer = dstring_newstr ();
|
||||
cmd_legacybuffer = dstring_newstr ();
|
||||
cmd_activebuffer = cmd_buffer;
|
||||
cmd_argbuf = dstring_newstr ();
|
||||
}
|
||||
|
||||
|
||||
void Cbuf_AddText (const char *text) {
|
||||
|
||||
dstring_appendstr (cmd_buffer, text);
|
||||
void
|
||||
Cbuf_AddTextTo (dstring_t *buffer, const char *text)
|
||||
{
|
||||
dstring_appendstr (buffer, text);
|
||||
}
|
||||
|
||||
void Cbuf_InsertText (const char *text) {
|
||||
dstring_insertstr (cmd_buffer, "\n", 0);
|
||||
dstring_insertstr (cmd_buffer, text, 0);
|
||||
/*
|
||||
Cbuf_AddText
|
||||
|
||||
Add text to the active buffer
|
||||
*/
|
||||
|
||||
void
|
||||
Cbuf_AddText (const char *text)
|
||||
{
|
||||
|
||||
Cbuf_AddTextTo (cmd_activebuffer, text);
|
||||
}
|
||||
|
||||
void extract_line (dstring_t *buffer) {
|
||||
void
|
||||
Cbuf_InsertTextTo (dstring_t *buffer, const char *text)
|
||||
{
|
||||
dstring_insertstr (buffer, "\n", 0);
|
||||
dstring_insertstr (buffer, text, 0);
|
||||
}
|
||||
|
||||
/* Cbuf_InsertText
|
||||
|
||||
Add text to the beginning of the active buffer
|
||||
*/
|
||||
|
||||
void
|
||||
Cbuf_InsertText (const char *text)
|
||||
{
|
||||
Cbuf_InsertTextTo (cmd_activebuffer, text);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
extract_line
|
||||
|
||||
Finds the next \n,\r, or ;-delimeted
|
||||
line in the command buffer and copies
|
||||
it into a buffer. Also shifts the rest
|
||||
of the command buffer back to the start.
|
||||
*/
|
||||
|
||||
void
|
||||
extract_line (dstring_t *buffer, dstring_t *line)
|
||||
{
|
||||
int i, squotes = 0, dquotes = 0;
|
||||
char *text = cmd_buffer->str;
|
||||
char *text = buffer->str;
|
||||
|
||||
for (i = 0; text[i]; i++) {
|
||||
if (text[i] == '\'' && !dquotes)
|
||||
|
@ -128,18 +171,28 @@ void extract_line (dstring_t *buffer) {
|
|||
break;
|
||||
}
|
||||
if (i)
|
||||
dstring_insert (buffer, cmd_buffer->str, i, 0);
|
||||
dstring_insert (line, buffer->str, i, 0);
|
||||
if (text[i])
|
||||
dstring_snip (cmd_buffer, 0, i + 1);
|
||||
dstring_snip (buffer, 0, i + 1);
|
||||
else // We've hit the end of the buffer, just clear it
|
||||
dstring_clearstr (cmd_buffer);
|
||||
dstring_clearstr (buffer);
|
||||
}
|
||||
|
||||
void Cbuf_Execute (void) {
|
||||
dstring_t *buf = dstring_newstr ();
|
||||
/*
|
||||
Cbuf_ExecuteBuffer
|
||||
|
||||
while (strlen(cmd_buffer->str)) {
|
||||
extract_line (buf);
|
||||
Extracts and executes each line in the
|
||||
command buffer, until it is empty or
|
||||
a wait command is executed
|
||||
*/
|
||||
|
||||
void
|
||||
Cbuf_ExecuteBuffer (dstring_t *buffer)
|
||||
{
|
||||
dstring_t *buf = dstring_newstr ();
|
||||
|
||||
while (strlen(buffer->str)) {
|
||||
extract_line (buffer, buf);
|
||||
Cmd_ExecuteString(buf->str, cmd_source);
|
||||
if (cmd_wait) {
|
||||
cmd_wait = false;
|
||||
|
@ -150,12 +203,34 @@ void Cbuf_Execute (void) {
|
|||
dstring_delete (buf);
|
||||
}
|
||||
|
||||
void Cbuf_Execute_Sets (void)
|
||||
void
|
||||
Cbuf_Execute (void)
|
||||
{
|
||||
cmd_activebuffer = cmd_legacybuffer; // Put legacy buffer into context
|
||||
cmd_legacy = true;
|
||||
Cbuf_ExecuteBuffer (cmd_activebuffer);
|
||||
cmd_legacy = false;
|
||||
cmd_activebuffer = cmd_buffer; // Next, do modern filtered buffer
|
||||
Cbuf_ExecuteBuffer (cmd_activebuffer);
|
||||
cmd_activebuffer = cmd_buffer; // The modern buffer should be in context by default
|
||||
}
|
||||
|
||||
/*
|
||||
Cbuf_Execute_Sets
|
||||
|
||||
Similar to Cbuf_Execute, but only
|
||||
executes set and setrom commands. Used
|
||||
for reading config files before the cmd
|
||||
subsystem is entirely loaded.
|
||||
*/
|
||||
|
||||
void
|
||||
Cbuf_Execute_Sets (void)
|
||||
{
|
||||
dstring_t *buf = dstring_newstr ();
|
||||
|
||||
while (strlen(cmd_buffer->str)) {
|
||||
extract_line (buf);
|
||||
extract_line (cmd_buffer, buf);
|
||||
if (!strncmp (buf->str, "set", 3) && isspace ((int) buf->str[3])) {
|
||||
Cmd_ExecuteString (buf->str, cmd_source);
|
||||
} else if (!strncmp (buf->str, "setrom", 6) && isspace ((int) buf->str[6])) {
|
||||
|
@ -322,7 +397,6 @@ Cmd_Alias_f (void)
|
|||
alias->next = *a;
|
||||
*a = alias;
|
||||
}
|
||||
printf("Aliasing %s to %s\n", Cmd_Argv(1), Cmd_Args(1));
|
||||
// copy the rest of the command line
|
||||
cmd = malloc (strlen (Cmd_Args (1)) + 2);// can never be longer
|
||||
if (!cmd)
|
||||
|
@ -398,7 +472,7 @@ Cmd_Argv (int arg)
|
|||
/*
|
||||
Cmd_Args
|
||||
|
||||
Returns a single string containing argv(1) to argv(argc()-1)
|
||||
Returns a single string containing argv(start) to argv(argc()-1)
|
||||
*/
|
||||
const char *
|
||||
Cmd_Args (int start)
|
||||
|
@ -450,34 +524,59 @@ int Cmd_GetToken (const char *str) {
|
|||
return i;
|
||||
}
|
||||
|
||||
int tag_gold = 0;
|
||||
int tag_shift = 0;
|
||||
int tag_special = 0;
|
||||
|
||||
struct stable_s {char a, b;} stable1[] =
|
||||
{
|
||||
{'f', 0x0D}, // Fake message
|
||||
|
||||
{'[', 0x90}, // Gold braces
|
||||
{']', 0x91},
|
||||
|
||||
{'(', 0x80}, // Scroll bar characters
|
||||
{'=', 0x81},
|
||||
{')', 0x82},
|
||||
{'|', 0x83},
|
||||
|
||||
{'<', 0x9D}, // Vertical line characters
|
||||
{'-', 0x9E},
|
||||
{'>', 0x9F},
|
||||
{'.', 0x8E}, // Gold dot
|
||||
{',', 0x0E}, // White dot
|
||||
{'G', 0x86}, // Ocrana leds from ocrana.wad
|
||||
{'R', 0x87},
|
||||
{'Y', 0x88},
|
||||
{'B', 0x89},
|
||||
{'a', 0x7F}, // White arrow
|
||||
|
||||
{'.', 0x05}, // White dot
|
||||
|
||||
{'#', 0x0B}, // White block
|
||||
|
||||
{'a', 0x7F}, // White arrow. DO NOT USE WITH <b> TAG IN ANYTHING SENT TO SERVER. PERIOD.
|
||||
{'A', 0x8D}, // Brown arrow
|
||||
|
||||
{'0', 0x92}, // Golden numbers
|
||||
{'1', 0x93},
|
||||
{'2', 0x94},
|
||||
{'3', 0x95},
|
||||
{'4', 0x96},
|
||||
{'5', 0x97},
|
||||
{'6', 0x98},
|
||||
{'7', 0x99},
|
||||
{'8', 0x9A},
|
||||
{'9', 0x9B},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
void Cmd_ProcessTags (dstring_t *dstr) {
|
||||
/*
|
||||
Cmd_ProcessTags
|
||||
|
||||
Looks for html-like tags in a dstring and
|
||||
modifies the string accordingly
|
||||
|
||||
FIXME: This has become messy. Create tag.[ch]
|
||||
and write a more generalized tag parser using
|
||||
callbacks
|
||||
*/
|
||||
|
||||
void
|
||||
Cmd_ProcessTags (dstring_t *dstr)
|
||||
{
|
||||
int close = 0, ignore = 0, i, n, c;
|
||||
char *str = dstr->str;
|
||||
|
||||
|
@ -499,14 +598,10 @@ void Cmd_ProcessTags (dstring_t *dstr) {
|
|||
}
|
||||
else if (ignore) // If ignore isn't being changed and we are ignore, go on
|
||||
continue;
|
||||
else if (!strncmp(str+i+close+1, "g", 1))
|
||||
tag_gold = close ? tag_gold - 1 : tag_gold + 1;
|
||||
else if (!strncmp(str+i+close+1, "b", 1))
|
||||
tag_shift = close ? tag_shift - 1 : tag_shift + 1;
|
||||
else if (!strncmp(str+i+close+1, "s", 1))
|
||||
tag_special = close ? tag_special - 1 : tag_special + 1;
|
||||
if (tag_gold < 0)
|
||||
tag_gold = 0;
|
||||
if (tag_shift < 0)
|
||||
tag_shift = 0;
|
||||
if (tag_special < 0)
|
||||
|
@ -519,19 +614,66 @@ void Cmd_ProcessTags (dstring_t *dstr) {
|
|||
/* This ignores escape characters, unless it is itself escaped */
|
||||
if (c == '\\' && (!i || str[i-1] != '\\'))
|
||||
continue;
|
||||
else if (tag_gold && c >='0' && c <= '9')
|
||||
c = (str[i] += (146 - '0'));
|
||||
else if (tag_special) {
|
||||
if (tag_special) {
|
||||
for (n = 0; stable1[n].a; n++)
|
||||
if (c == stable1[n].a)
|
||||
c = str[i] = stable1[n].b;
|
||||
}
|
||||
else if (tag_shift && c < 128)
|
||||
if (tag_shift && c < 128)
|
||||
c = (str[i] += 128);
|
||||
}
|
||||
}
|
||||
|
||||
void Cmd_ProcessEscapes (dstring_t *dstr) {
|
||||
/*
|
||||
Cmd_ProcessVariables
|
||||
|
||||
Looks for occurances of ${varname} and
|
||||
replaces them with the contents of the
|
||||
variable.
|
||||
*/
|
||||
|
||||
void
|
||||
Cmd_ProcessVariables (dstring_t *dstr)
|
||||
{
|
||||
char *str = dstr->str;
|
||||
dstring_t *varname;
|
||||
cvar_t *var;
|
||||
int i, n;
|
||||
|
||||
varname = dstring_newstr ();
|
||||
|
||||
for (i = 0; i < strlen(str); i++) {
|
||||
if (str[i] == '$' && str[i+1] == '{' && (!i || str[i-1] != '\\')) {
|
||||
for (n = 0; str[i+n] != '}'; n++)
|
||||
if (!str[i+n])
|
||||
return; // Open curly braces, give up
|
||||
/* Copy text between braces into a buffer */
|
||||
dstring_clearstr (varname);
|
||||
dstring_insert (varname, str+i+2, n-2, 0);
|
||||
var = 0;
|
||||
var = Cvar_FindVar(varname->str);
|
||||
if (var) {// Do we have a match?
|
||||
dstring_snip (dstr, i, n+1); // Nuke it
|
||||
dstring_insertstr (dstr, var->string, i); // Stick in the value of variable
|
||||
}
|
||||
}
|
||||
}
|
||||
dstring_delete (varname);
|
||||
}
|
||||
|
||||
/*
|
||||
Cmd_ProcessEscapes
|
||||
|
||||
Looks for the escape character \ and
|
||||
removes it. Special cases exist for
|
||||
\\ and \n; otherwise, it is simply
|
||||
filtered. This should be the last
|
||||
step in the parser so that quotes,
|
||||
tags, etc. can be escaped
|
||||
*/
|
||||
|
||||
void
|
||||
Cmd_ProcessEscapes (dstring_t *dstr) {
|
||||
int i;
|
||||
char *str = dstr->str;
|
||||
|
||||
|
@ -547,18 +689,39 @@ void Cmd_ProcessEscapes (dstring_t *dstr) {
|
|||
}
|
||||
}
|
||||
|
||||
void Cmd_TokenizeString (const char *text) {
|
||||
/*
|
||||
Cmd_TokenizeString
|
||||
|
||||
This takes a normal string, parses it
|
||||
into tokens, runs various filters on
|
||||
each token, and recombines them with the
|
||||
correct white space into a string for
|
||||
the purpose of executing a console
|
||||
command. If the string begins with a \,
|
||||
filters are not run and the \ is stripped.
|
||||
Anything that stuffs commands into the
|
||||
console that requires absolute backwards
|
||||
compatibility should be changed to prepend
|
||||
it with a \. An example of this is
|
||||
fullserverinfo, which requires that \
|
||||
be left alone since it is the delimeter
|
||||
for info keys.
|
||||
*/
|
||||
|
||||
void
|
||||
Cmd_TokenizeString (const char *text, qboolean filter)
|
||||
{
|
||||
int i = 0, n, len = 0, quotes = 0, space;
|
||||
const char *str = text;
|
||||
|
||||
cmd_argc = 0;
|
||||
|
||||
/* Turn off tags at the beginning of a command.
|
||||
This causes tags to continue past token boundaries. */
|
||||
tag_shift = 0;
|
||||
tag_gold = 0;
|
||||
tag_special = 0;
|
||||
printf("String in: %s\n", text);
|
||||
if (text[0] == '|')
|
||||
str++;
|
||||
printf("Tokenizing: %s\n", str);
|
||||
while (strlen(str + i)) {
|
||||
space = 0;
|
||||
while (isspace(str[i])) {
|
||||
|
@ -583,8 +746,8 @@ void Cmd_TokenizeString (const char *text) {
|
|||
cmd_maxargc++;
|
||||
}
|
||||
dstring_clearstr(cmd_argv[cmd_argc-1]);
|
||||
/* Remove surrounding quotes or double quotes */
|
||||
cmd_argspace[cmd_argc-1] = space;
|
||||
/* Remove surrounding quotes or double quotes */
|
||||
quotes = 0;
|
||||
if ((str[i] == '\'' && str[i+len] == '\'') || (str[i] == '"' && str[i+len] == '"')) {
|
||||
i++;
|
||||
|
@ -592,8 +755,9 @@ void Cmd_TokenizeString (const char *text) {
|
|||
quotes = 1;
|
||||
}
|
||||
dstring_insert(cmd_argv[cmd_argc-1], str + i, len, 0);
|
||||
if (text[0] != '|') { // Lines beginning with | are not modified
|
||||
if (filter) {
|
||||
Cmd_ProcessTags(cmd_argv[cmd_argc-1]);
|
||||
Cmd_ProcessVariables(cmd_argv[cmd_argc-1]);
|
||||
Cmd_ProcessEscapes(cmd_argv[cmd_argc-1]);
|
||||
}
|
||||
i += len + quotes; /* If we ended on a quote, skip it */
|
||||
|
@ -831,76 +995,6 @@ Cmd_CompleteAliasBuildList (const char *partial)
|
|||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
Cmd_ExpandVariables
|
||||
|
||||
Expand $fov-like expressions
|
||||
FIXME: better handling of buffer overflows?
|
||||
*/
|
||||
// dest must point to a 1024-byte buffer
|
||||
void
|
||||
Cmd_ExpandVariables (const char *data, char *dest)
|
||||
{
|
||||
unsigned int c;
|
||||
char buf[1024];
|
||||
int i, len;
|
||||
cvar_t *bestvar;
|
||||
int quotes = 0;
|
||||
|
||||
len = 0;
|
||||
|
||||
// parse a regular word
|
||||
while ((c = *data) != 0) {
|
||||
if (c == '"')
|
||||
quotes++;
|
||||
if (c == '$' && *(data+1) == '{' && !(quotes & 1)) {
|
||||
data+=2;
|
||||
// Copy the text between the braces to a temp buffer
|
||||
i = 0;
|
||||
buf[0] = 0;
|
||||
bestvar = NULL;
|
||||
while ((c = *data) != 0 && c != '}') {
|
||||
data++;
|
||||
buf[i++] = c;
|
||||
buf[i] = 0;
|
||||
if (i >= sizeof (buf) - 1)
|
||||
break;
|
||||
}
|
||||
data++;
|
||||
bestvar = Cvar_FindVar(buf);
|
||||
|
||||
if (bestvar) {
|
||||
// check buffer size
|
||||
if (len + strlen (bestvar->string) >= 1024 - 1)
|
||||
break;
|
||||
|
||||
strcpy (&dest[len], bestvar->string);
|
||||
len += strlen (bestvar->string);
|
||||
i = strlen (bestvar->name);
|
||||
while (buf[i])
|
||||
dest[len++] = buf[i++];
|
||||
} else {
|
||||
// no matching cvar name was found
|
||||
dest[len++] = '$';
|
||||
dest[len++] = '{';
|
||||
if (len + strlen (buf) >= 1024)
|
||||
break;
|
||||
strcpy (&dest[len], buf);
|
||||
len += strlen (buf);
|
||||
dest[len++] = '}';
|
||||
}
|
||||
} else {
|
||||
dest[len] = c;
|
||||
data++;
|
||||
len++;
|
||||
if (len >= 1024 - 1)
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
dest[len] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Cmd_ExecuteString
|
||||
|
||||
|
@ -913,7 +1007,7 @@ Cmd_ExecuteString (const char *text, cmd_source_t src)
|
|||
cmdalias_t *a;
|
||||
cmd_source = src;
|
||||
|
||||
Cmd_TokenizeString (text);
|
||||
Cmd_TokenizeString (text, !cmd_legacy);
|
||||
|
||||
// execute the command line
|
||||
if (!Cmd_Argc ())
|
||||
|
@ -1167,46 +1261,3 @@ skipwhite:
|
|||
write_com_token (len, 0);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Cmd_ParseSpecial (char *s)
|
||||
{
|
||||
char *d;
|
||||
int i, i2;
|
||||
char c = 0;
|
||||
|
||||
i = 0;
|
||||
d = s;
|
||||
|
||||
while (*s) {
|
||||
if ((*s == '\\') && ((s[1] == '#') || (s[1] == '$') || (s[1] == '\\'))) {
|
||||
d[i++] = s[1];
|
||||
s+=2;
|
||||
continue;
|
||||
}
|
||||
if ((*s == '$') && (s[1] != '\0')) {
|
||||
for (i2 = 0; stable1[i2].a; i2++) {
|
||||
if (s[1] == stable1[i2].a) {
|
||||
c = stable1[i2].b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c) {
|
||||
d[i++] = c;
|
||||
s += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((*s == '#') && (s[1] != '\0')) {
|
||||
d[i++] = s[1] ^ 128;
|
||||
s += 2;
|
||||
continue;
|
||||
}
|
||||
d[i++] = *s++;
|
||||
}
|
||||
d[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1208,8 +1208,7 @@ CL_ParseServerMessage (void)
|
|||
case svc_stufftext:
|
||||
s = MSG_ReadString (net_message);
|
||||
Con_DPrintf ("stufftext: %s\n", s);
|
||||
Cbuf_AddText ("|"); // Make command be executed in a backward-compatible fashion
|
||||
Cbuf_AddText (s);
|
||||
Cbuf_AddTextTo (cmd_legacybuffer, s);
|
||||
break;
|
||||
|
||||
case svc_damage:
|
||||
|
|
|
@ -512,7 +512,7 @@ SVC_Status (void)
|
|||
return;
|
||||
|
||||
con_printf_no_log = 1;
|
||||
Cmd_TokenizeString ("status");
|
||||
Cmd_TokenizeString ("status", false);
|
||||
SV_BeginRedirect (RD_PACKET);
|
||||
SV_Printf ("%s\n", Info_MakeString (svs.info, 0));
|
||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||
|
@ -1026,7 +1026,7 @@ SV_ConnectionlessPacket (void)
|
|||
|
||||
s = MSG_ReadString (net_message);
|
||||
|
||||
Cmd_TokenizeString (s);
|
||||
Cmd_TokenizeString (s, false);
|
||||
|
||||
c = Cmd_Argv (0);
|
||||
|
||||
|
|
|
@ -1240,7 +1240,7 @@ SV_ExecuteUserCommand (const char *s)
|
|||
ucmd_t *u;
|
||||
ucmd_t cmd;
|
||||
|
||||
Cmd_TokenizeString (s);
|
||||
Cmd_TokenizeString (s, false);
|
||||
sv_player = host_client->edict;
|
||||
cmd.name = Cmd_Argv(0);
|
||||
|
||||
|
|
Loading…
Reference in a new issue