mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
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:
parent
9aeef3f3d6
commit
ecff96258f
10 changed files with 188 additions and 27 deletions
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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!");
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue