cmd.[ch]:

api change: Cmd_Args () now takes a parameter inidcating which arg to
	start at for grabbing the un-parsed command line
qw/source/sv_ccmds.c:
	implement kk's tell command and user name matching (though # is used for
	the wildcard and it's still case sensitive)
everything else:
	adjust for the new Cmd_Args protype
This commit is contained in:
Bill Currie 2001-07-10 18:25:54 +00:00
parent 9aeef3f3d6
commit ecff96258f
10 changed files with 188 additions and 27 deletions

View File

@ -116,7 +116,7 @@ char *Cmd_CompleteAlias (char *partial);
int Cmd_Argc (void);
char *Cmd_Argv (int arg);
char *Cmd_Args (void);
char *Cmd_Args (int start);
// The functions that execute commands get their parameters with these
// functions. Cmd_Argv () will return an empty string, not a NULL
// if arg > argc, so string operations are always safe.

View File

@ -409,7 +409,7 @@ Cmd_Alias_f (void)
}
// copy the rest of the command line
cmd = malloc (strlen (Cmd_Args ()) + 2);// can never be longer
cmd = malloc (strlen (Cmd_Args (1)) + 2);// can never be longer
cmd[0] = 0; // start out with a null string
c = Cmd_Argc ();
for (i = 2; i < c; i++) {
@ -468,7 +468,7 @@ typedef struct cmd_function_s {
static int cmd_argc;
static char *cmd_argv[MAX_ARGS];
static char *cmd_null_string = "";
static char *cmd_args = NULL;
static char *cmd_args[MAX_ARGS];
@ -500,11 +500,11 @@ Cmd_Argv (int arg)
Returns a single string containing argv(1) to argv(argc()-1)
*/
char *
Cmd_Args (void)
Cmd_Args (int start)
{
if (!cmd_args)
if (start >= cmd_argc || !cmd_args[start])
return "";
return cmd_args;
return cmd_args[start];
}
@ -522,7 +522,7 @@ Cmd_TokenizeString (char *text)
argv_idx = 0;
cmd_argc = 0;
cmd_args = NULL;
memset (cmd_args, 0, sizeof (cmd_args));
while (1) {
// skip whitespace up to a /n
@ -539,8 +539,8 @@ Cmd_TokenizeString (char *text)
if (!*text)
return;
if (cmd_argc == 1)
cmd_args = text;
if (cmd_argc < MAX_ARGS)
cmd_args[cmd_argc] = text;
text = COM_Parse (text);
if (!text)

View File

@ -64,7 +64,7 @@ Cmd_ForwardToServer (void)
SZ_Print (&cls.message, " ");
}
if (Cmd_Argc () > 1)
SZ_Print (&cls.message, Cmd_Args ());
SZ_Print (&cls.message, Cmd_Args (1));
else
SZ_Print (&cls.message, "\n");
}

View File

@ -926,7 +926,7 @@ Host_Name_f (void)
if (Cmd_Argc () == 2)
newName = Cmd_Argv (1);
else
newName = Cmd_Args ();
newName = Cmd_Args (1);
newName[15] = 0;
if (cmd_source == src_command) {
@ -985,7 +985,7 @@ Host_Say (qboolean teamonly)
save = host_client;
p = Cmd_Args ();
p = Cmd_Args (1);
// remove quotes if present
if (*p == '"') {
p++;
@ -1052,7 +1052,7 @@ Host_Tell_f (void)
strcpy (text, host_client->name);
strcat (text, ": ");
p = Cmd_Args ();
p = Cmd_Args (1);
// remove quotes if present
if (*p == '"') {
@ -1367,7 +1367,7 @@ Host_Kick_f (void)
return;
if (Cmd_Argc () > 2) {
message = COM_Parse (Cmd_Args ());
message = COM_Parse (Cmd_Args (1));
if (byNumber) {
message++; // skip the #
while (*message == ' ') // skip white space

View File

@ -71,7 +71,7 @@ Cmd_ForwardToServer (void)
!strcasecmp (Cmd_Argv (0), "say_team")) {
char *s;
s = Team_ParseSay (Cmd_Args ());
s = Team_ParseSay (Cmd_Args (1));
if (*s && *s < 32 && *s != 10) {
// otherwise the server would eat leading characters
// less than 32 or greater than 127
@ -83,7 +83,7 @@ Cmd_ForwardToServer (void)
return;
}
SZ_Print (&cls.netchan.message, Cmd_Args ());
SZ_Print (&cls.netchan.message, Cmd_Args (1));
}
}
@ -107,7 +107,7 @@ Cmd_ForwardToServer_f (void)
if (Cmd_Argc () > 1) {
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
SZ_Print (&cls.netchan.message, Cmd_Args ());
SZ_Print (&cls.netchan.message, Cmd_Args (1));
}
}

View File

@ -59,6 +59,46 @@ char fp_msg[255] = { 0 };
extern cvar_t *cl_warncmd;
extern redirect_t sv_redirected;
qboolean
SV_Match_User (const char *substr, int *uidp)
{
int i, j;
int count = 0;
char *str;
client_t *cl;
if (!substr[0]) {
*uidp = 0;
Con_Printf ("Too many matches, ignoring command!\n");
return false;
}
for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) {
if (!cl->state)
continue;
str = strchr (cl->name, substr[0]);
while (str) {
for (j = 0; substr[j] && str[j]; j++)
if (sys_char_map[(byte)substr[j]] != sys_char_map[(byte)str[j]])
break;
if (!substr[j]) { // found a match;
*uidp = cl->userid;
count++;
Con_Printf ("User %04d matches with name: %s\n",
*uidp, cl->name);
str = 0;
} else {
str = strchr (str + 1, substr[0]);
}
}
}
if (count > 1) {
*uidp = 0;
Con_Printf ("Too many matches, ignoring command!\n");
}
if (count)
return true;
return false;
}
/*
OPERATOR CONSOLE ONLY COMMANDS
@ -367,7 +407,16 @@ SV_Kick_f (void)
client_t *cl;
int uid;
uid = atoi (Cmd_Argv (1));
if (Cmd_Argc () != 2) {
Con_Printf ("usage: kick <name/userid>\n");
return;
}
if (SV_Match_User (Cmd_Argv(1), &uid)) {
if (!uid)
return;
} else {
uid = atoi (Cmd_Argv (1));
}
for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) {
if (!cl->state)
@ -484,6 +533,51 @@ SV_Status_f (void)
Con_Printf ("\n");
}
void
SV_Tell (const char *prefix)
{
int i;
int uid;
client_t *cl;
char *p;
char text[512];
if (Cmd_Argc () < 3) {
Con_Printf ("usage: tell <name/userid> <text...>\n");
return;
}
if (SV_Match_User (Cmd_Argv(1), &uid)) {
if (!uid)
return;
} else {
uid = atoi (Cmd_Argv(1));
}
p = Cmd_Args (2);
if (*p == '"') {
p++;
p[strlen (p) - 1] = 0;
}
// construct "[PRIVATE] Console> "
sprintf (text, "[\xd0\xd2\xc9\xd6\xc1\xd4\xc5] %s\x8d ", prefix);
i = strlen (text);
strncat (text, p, sizeof (text) - 1 - i);
text[sizeof (text) - 1] = 0;
for (; text[i];)
text[i++] |= 0x80; // non-bold text
for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) {
if (!cl->state)
continue;
if (cl->userid == uid) {
SV_ClientPrintf(cl, PRINT_CHAT, "\n"); // bell
SV_ClientPrintf(cl, PRINT_HIGH, "%s\n", text);
SV_ClientPrintf(cl, PRINT_CHAT, "%s", ""); // bell
return;
}
}
Con_Printf ("Couldn't find user %s\n", Cmd_Argv(1));
}
void
SV_ConSay (const char *prefix)
{
@ -495,7 +589,7 @@ SV_ConSay (const char *prefix)
if (Cmd_Argc () < 2)
return;
p = Cmd_Args ();
p = Cmd_Args (1);
if (*p == '"') {
p++;
p[strlen (p) - 1] = 0;
@ -516,6 +610,18 @@ SV_ConSay (const char *prefix)
}
}
/*
SV_Tell_f
*/
void
SV_Tell_f (void)
{
if (rcon_from_user)
SV_Tell("Admin");
else
SV_Tell("Console");
}
/*
SV_ConSay_f
*/
@ -901,12 +1007,12 @@ SV_InitOperatorCommands (void)
Cmd_AddCommand ("maplist", COM_Maplist_f, "List all maps on the server");
Cmd_AddCommand ("say", SV_ConSay_f, "Say something to everyone on the server, will show up as the name 'Console' (or 'Admin') in game");
Cmd_AddCommand ("sayinfo", SV_ConSay_Info_f, "Say something to everyone on the server, will show up as the name 'Info' in game");
Cmd_AddCommand ("say", SV_ConSay_f, "Say something to everyone on the server. Will show up as the name 'Console' (or 'Admin') in game");
Cmd_AddCommand ("sayinfo", SV_ConSay_Info_f, "Say something to everyone on the server. Will show up as the name 'Info' in game");
Cmd_AddCommand ("tell", SV_Tell_f, "Say something to a specific user on the server. Will show up as the name 'Console' (or 'Admin') in game");
//XXX Cmd_AddCommand ("ban", SV_Ban_f);
//XXX Cmd_AddCommand ("cuff", SV_Cuff_f);
//XXX Cmd_AddCommand ("mute", SV_Mute_f);
//XXX Cmd_AddCommand ("tell", SV_Tell_f);
//XXX Cmd_AddCommand ("ban", SV_Ban_f);
cl_warncmd =
Cvar_Get ("cl_warncmd", "1", CVAR_NONE, NULL,

View File

@ -810,7 +810,7 @@ SV_Say (qboolean team)
host_client->whensaid[host_client->whensaidhead] = realtime;
}
p = Cmd_Args ();
p = Cmd_Args (1);
if (*p == '"') {
p++;
@ -844,7 +844,6 @@ SV_Say (qboolean team)
}
}
/*
SV_Say_f
*/

View File

@ -361,7 +361,7 @@ locs_loc (void)
return;
}
if (Cmd_Argc () >= 3)
desc = Cmd_Args () + strlen(Cmd_Argv(1)) + 1;
desc = Cmd_Args (2);
mapname = malloc(sizeof(cl.worldmodel->name));
if (!mapname)
Sys_Error ("Can't duplicate mapname!");

View File

@ -75,7 +75,6 @@ main ()
printf (" %d", func->parm_size[j]);
printf ("\n");
}
#if 0
printf ("\n");
for (i = 0; i < progs.progs->numglobaldefs; i++) {
ddef_t *def = &progs.pr_globaldefs[i];
@ -83,6 +82,7 @@ main ()
printf ("%s %d %d %s\n", type_name[def->type & ~DEF_SAVEGLOBAL], (def->type & DEF_SAVEGLOBAL) != 0, def->ofs, PR_GetString (&progs, def->s_name));
}
printf ("\n");
#if 0
for (i = 0; i < progs.progs->numfielddefs; i++) {
ddef_t *def = &progs.pr_fielddefs[i];

View File

@ -63,3 +63,59 @@ void () eek =
self.origin = self.origin + '1 2 3';
traceoff();
};
.string classname;
.string netname;
float (entity tester) IsBuilding =
{
if (
tester.classname == "building_sentrygun" ||
tester.classname == "building_sentrygun_base" ||
tester.classname == "building_tesla" ||
tester.classname == "building_dispenser" ||
tester.classname == "building_camera" ||
tester.classname == "building_arawana" ||
tester.classname == "building_teleporter"||
tester.classname == "building_fieldgen"||
tester.classname == "building_sensor"
)
return 1;
return 0;
};
float(entity thing) IsMonster =
{
if (thing.classname=="monster_shambler")
return 1;
if (thing.classname=="monster_demon1")
return 1;
if (thing.classname=="monster_wizard")
return 1;
if (thing.classname=="monster_army")
return 1;
if (thing.classname=="monster_knight")
return 1;
if (thing.classname=="monster_hknight")
return 1;
return 0;
};
string(entity thething) GetEnemyName =
{
if (thething.classname == "player")
return thething.netname;
if (IsMonster(thething))
return "";
if (IsBuilding(thething))
return "";
if (thething.classname == "grenade" && thething.netname == "land_mine")
return "land mine";
if (thething.classname != "")
return thething.classname;
return "unknown stuff";
};