|
|
1.1.1.3 ! root 1: /* ! 2: Copyright (C) 1997-2001 Id Software, Inc. ! 3: ! 4: This program is free software; you can redistribute it and/or ! 5: modify it under the terms of the GNU General Public License ! 6: as published by the Free Software Foundation; either version 2 ! 7: of the License, or (at your option) any later version. ! 8: ! 9: This program is distributed in the hope that it will be useful, ! 10: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! 12: ! 13: See the GNU General Public License for more details. ! 14: ! 15: You should have received a copy of the GNU General Public License ! 16: along with this program; if not, write to the Free Software ! 17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! 18: ! 19: */ 1.1 root 20: // cmd.c -- Quake script command processing module 1.1.1.2 root 21: 1.1 root 22: #include "qcommon.h" 1.1.1.2 root 23: 1.1 root 24: void Cmd_ForwardToServer (void); 1.1.1.2 root 25: 1.1 root 26: #define MAX_ALIAS_NAME 32 1.1.1.2 root 27: 1.1 root 28: typedef struct cmdalias_s 29: { 30: struct cmdalias_s *next; 31: char name[MAX_ALIAS_NAME]; 32: char *value; 33: } cmdalias_t; 1.1.1.2 root 34: 1.1 root 35: cmdalias_t *cmd_alias; 1.1.1.2 root 36: 1.1 root 37: qboolean cmd_wait; 1.1.1.2 root 38: 1.1 root 39: #define ALIAS_LOOP_COUNT 16 40: int alias_count; // for detecting runaway loops 1.1.1.2 root 41: 42: 1.1 root 43: //============================================================================= 1.1.1.2 root 44: 1.1 root 45: /* 46: ============ 47: Cmd_Wait_f 1.1.1.2 root 48: 1.1 root 49: Causes execution of the remainder of the command buffer to be delayed until 50: next frame. This allows commands like: 51: bind g "impulse 5 ; +attack ; wait ; -attack ; impulse 2" 52: ============ 53: */ 54: void Cmd_Wait_f (void) 55: { 56: cmd_wait = true; 57: } 58: 1.1.1.2 root 59: 1.1 root 60: /* 61: ============================================================================= 1.1.1.2 root 62: 1.1 root 63: COMMAND BUFFER 1.1.1.2 root 64: 1.1 root 65: ============================================================================= 66: */ 1.1.1.2 root 67: 1.1 root 68: sizebuf_t cmd_text; 69: byte cmd_text_buf[8192]; 70: 71: byte defer_text_buf[8192]; 1.1.1.2 root 72: 1.1 root 73: /* 74: ============ 75: Cbuf_Init 76: ============ 77: */ 78: void Cbuf_Init (void) 79: { 80: SZ_Init (&cmd_text, cmd_text_buf, sizeof(cmd_text_buf)); 81: } 82: 83: /* 84: ============ 85: Cbuf_AddText 1.1.1.2 root 86: 1.1 root 87: Adds command text at the end of the buffer 88: ============ 89: */ 90: void Cbuf_AddText (char *text) 91: { 92: int l; 93: 94: l = strlen (text); 1.1.1.2 root 95: 1.1 root 96: if (cmd_text.cursize + l >= cmd_text.maxsize) 97: { 98: Com_Printf ("Cbuf_AddText: overflow\n"); 99: return; 100: } 101: SZ_Write (&cmd_text, text, strlen (text)); 102: } 1.1.1.2 root 103: 104: 1.1 root 105: /* 106: ============ 107: Cbuf_InsertText 1.1.1.2 root 108: 1.1 root 109: Adds command text immediately after the current command 110: Adds a \n to the text 111: FIXME: actually change the command buffer to do less copying 112: ============ 113: */ 114: void Cbuf_InsertText (char *text) 115: { 116: char *temp; 117: int templen; 1.1.1.2 root 118: 1.1 root 119: // copy off any commands still remaining in the exec buffer 120: templen = cmd_text.cursize; 121: if (templen) 122: { 123: temp = Z_Malloc (templen); 124: memcpy (temp, cmd_text.data, templen); 125: SZ_Clear (&cmd_text); 126: } 127: else 128: temp = NULL; // shut up compiler 129: 130: // add the entire text of the file 131: Cbuf_AddText (text); 132: 133: // add the copied off data 134: if (templen) 135: { 136: SZ_Write (&cmd_text, temp, templen); 137: Z_Free (temp); 138: } 139: } 140: 1.1.1.2 root 141: 1.1 root 142: /* 143: ============ 144: Cbuf_CopyToDefer 145: ============ 146: */ 147: void Cbuf_CopyToDefer (void) 148: { 149: memcpy(defer_text_buf, cmd_text_buf, cmd_text.cursize); 150: defer_text_buf[cmd_text.cursize] = 0; 151: cmd_text.cursize = 0; 152: } 153: 154: /* 155: ============ 156: Cbuf_InsertFromDefer 157: ============ 158: */ 159: void Cbuf_InsertFromDefer (void) 160: { 161: Cbuf_InsertText (defer_text_buf); 162: defer_text_buf[0] = 0; 163: } 164: 165: 166: /* 167: ============ 168: Cbuf_ExecuteText 169: ============ 170: */ 171: void Cbuf_ExecuteText (int exec_when, char *text) 172: { 173: switch (exec_when) 174: { 175: case EXEC_NOW: 176: Cmd_ExecuteString (text); 177: break; 178: case EXEC_INSERT: 179: Cbuf_InsertText (text); 180: break; 181: case EXEC_APPEND: 182: Cbuf_AddText (text); 183: break; 184: default: 185: Com_Error (ERR_FATAL, "Cbuf_ExecuteText: bad exec_when"); 186: } 187: } 1.1.1.2 root 188: 1.1 root 189: /* 190: ============ 191: Cbuf_Execute 192: ============ 193: */ 194: void Cbuf_Execute (void) 195: { 196: int i; 197: char *text; 198: char line[1024]; 199: int quotes; 200: 201: alias_count = 0; // don't allow infinite alias loops 1.1.1.2 root 202: 1.1 root 203: while (cmd_text.cursize) 204: { 205: // find a \n or ; line break 206: text = (char *)cmd_text.data; 1.1.1.2 root 207: 1.1 root 208: quotes = 0; 209: for (i=0 ; i< cmd_text.cursize ; i++) 210: { 211: if (text[i] == '"') 212: quotes++; 213: if ( !(quotes&1) && text[i] == ';') 214: break; // don't break if inside a quoted string 215: if (text[i] == '\n') 216: break; 217: } 218: 219: 220: memcpy (line, text, i); 221: line[i] = 0; 222: 223: // delete the text from the command buffer and move remaining commands down 224: // this is necessary because commands (exec, alias) can insert data at the 225: // beginning of the text buffer 1.1.1.2 root 226: 1.1 root 227: if (i == cmd_text.cursize) 228: cmd_text.cursize = 0; 229: else 230: { 231: i++; 232: cmd_text.cursize -= i; 233: memmove (text, text+i, cmd_text.cursize); 234: } 1.1.1.2 root 235: 1.1 root 236: // execute the command line 237: Cmd_ExecuteString (line); 238: 239: if (cmd_wait) 240: { 241: // skip out while text still remains in buffer, leaving it 242: // for next frame 243: cmd_wait = false; 244: break; 245: } 246: } 247: } 1.1.1.2 root 248: 249: 1.1 root 250: /* 251: =============== 252: Cbuf_AddEarlyCommands 1.1.1.2 root 253: 1.1 root 254: Adds command line parameters as script statements 255: Commands lead with a +, and continue until another + 1.1.1.2 root 256: 1.1 root 257: Set commands are added early, so they are guaranteed to be set before 258: the client and server initialize for the first time. 1.1.1.2 root 259: 1.1 root 260: Other commands are added late, after all initialization is complete. 261: =============== 262: */ 263: void Cbuf_AddEarlyCommands (qboolean clear) 264: { 265: int i; 266: char *s; 1.1.1.2 root 267: 1.1 root 268: for (i=0 ; i<COM_Argc() ; i++) 269: { 270: s = COM_Argv(i); 271: if (strcmp (s, "+set")) 272: continue; 273: Cbuf_AddText (va("set %s %s\n", COM_Argv(i+1), COM_Argv(i+2))); 274: if (clear) 275: { 276: COM_ClearArgv(i); 277: COM_ClearArgv(i+1); 278: COM_ClearArgv(i+2); 279: } 280: i+=2; 281: } 282: } 1.1.1.2 root 283: 1.1 root 284: /* 285: ================= 286: Cbuf_AddLateCommands 1.1.1.2 root 287: 1.1 root 288: Adds command line parameters as script statements 289: Commands lead with a + and continue until another + or - 290: quake +vid_ref gl +map amlev1 1.1.1.2 root 291: 1.1 root 292: Returns true if any late commands were added, which 293: will keep the demoloop from immediately starting 294: ================= 295: */ 296: qboolean Cbuf_AddLateCommands (void) 297: { 298: int i, j; 299: int s; 300: char *text, *build, c; 301: int argc; 302: qboolean ret; 1.1.1.2 root 303: 1.1 root 304: // build the combined string to parse from 305: s = 0; 306: argc = COM_Argc(); 307: for (i=1 ; i<argc ; i++) 308: { 309: s += strlen (COM_Argv(i)) + 1; 310: } 311: if (!s) 312: return false; 313: 314: text = Z_Malloc (s+1); 315: text[0] = 0; 316: for (i=1 ; i<argc ; i++) 317: { 318: strcat (text,COM_Argv(i)); 319: if (i != argc-1) 320: strcat (text, " "); 321: } 322: 323: // pull out the commands 324: build = Z_Malloc (s+1); 325: build[0] = 0; 326: 327: for (i=0 ; i<s-1 ; i++) 328: { 329: if (text[i] == '+') 330: { 331: i++; 1.1.1.2 root 332: 1.1 root 333: for (j=i ; (text[j] != '+') && (text[j] != '-') && (text[j] != 0) ; j++) 334: ; 1.1.1.2 root 335: 1.1 root 336: c = text[j]; 337: text[j] = 0; 338: 339: strcat (build, text+i); 340: strcat (build, "\n"); 341: text[j] = c; 342: i = j-1; 343: } 344: } 1.1.1.2 root 345: 1.1 root 346: ret = (build[0] != 0); 347: if (ret) 348: Cbuf_AddText (build); 349: 350: Z_Free (text); 351: Z_Free (build); 1.1.1.2 root 352: 1.1 root 353: return ret; 354: } 1.1.1.2 root 355: 356: 1.1 root 357: /* 358: ============================================================================== 1.1.1.2 root 359: 1.1 root 360: SCRIPT COMMANDS 1.1.1.2 root 361: 1.1 root 362: ============================================================================== 363: */ 1.1.1.2 root 364: 365: 1.1 root 366: /* 367: =============== 368: Cmd_Exec_f 369: =============== 370: */ 371: void Cmd_Exec_f (void) 372: { 373: char *f, *f2; 374: int len; 1.1.1.2 root 375: 1.1 root 376: if (Cmd_Argc () != 2) 377: { 378: Com_Printf ("exec <filename> : execute a script file\n"); 379: return; 380: } 1.1.1.2 root 381: 1.1 root 382: len = FS_LoadFile (Cmd_Argv(1), (void **)&f); 383: if (!f) 384: { 385: Com_Printf ("couldn't exec %s\n",Cmd_Argv(1)); 386: return; 387: } 388: Com_Printf ("execing %s\n",Cmd_Argv(1)); 389: 390: // the file doesn't have a trailing 0, so we need to copy it off 391: f2 = Z_Malloc(len+1); 392: memcpy (f2, f, len); 393: f2[len] = 0; 1.1.1.2 root 394: 1.1 root 395: Cbuf_InsertText (f2); 1.1.1.2 root 396: 1.1 root 397: Z_Free (f2); 398: FS_FreeFile (f); 399: } 1.1.1.2 root 400: 401: 1.1 root 402: /* 403: =============== 404: Cmd_Echo_f 1.1.1.2 root 405: 1.1 root 406: Just prints the rest of the line to the console 407: =============== 408: */ 409: void Cmd_Echo_f (void) 410: { 411: int i; 412: 413: for (i=1 ; i<Cmd_Argc() ; i++) 414: Com_Printf ("%s ",Cmd_Argv(i)); 415: Com_Printf ("\n"); 416: } 1.1.1.2 root 417: 1.1 root 418: /* 419: =============== 420: Cmd_Alias_f 1.1.1.2 root 421: 1.1 root 422: Creates a new command that executes a command string (possibly ; seperated) 423: =============== 424: */ 425: void Cmd_Alias_f (void) 426: { 427: cmdalias_t *a; 428: char cmd[1024]; 429: int i, c; 430: char *s; 1.1.1.2 root 431: 1.1 root 432: if (Cmd_Argc() == 1) 433: { 434: Com_Printf ("Current alias commands:\n"); 435: for (a = cmd_alias ; a ; a=a->next) 436: Com_Printf ("%s : %s\n", a->name, a->value); 437: return; 438: } 1.1.1.2 root 439: 1.1 root 440: s = Cmd_Argv(1); 441: if (strlen(s) >= MAX_ALIAS_NAME) 442: { 443: Com_Printf ("Alias name is too long\n"); 444: return; 445: } 1.1.1.2 root 446: 1.1 root 447: // if the alias already exists, reuse it 448: for (a = cmd_alias ; a ; a=a->next) 449: { 450: if (!strcmp(s, a->name)) 451: { 452: Z_Free (a->value); 453: break; 454: } 455: } 1.1.1.2 root 456: 1.1 root 457: if (!a) 458: { 459: a = Z_Malloc (sizeof(cmdalias_t)); 460: a->next = cmd_alias; 461: cmd_alias = a; 462: } 463: strcpy (a->name, s); 1.1.1.2 root 464: 1.1 root 465: // copy the rest of the command line 466: cmd[0] = 0; // start out with a null string 467: c = Cmd_Argc(); 468: for (i=2 ; i< c ; i++) 469: { 470: strcat (cmd, Cmd_Argv(i)); 471: if (i != (c - 1)) 472: strcat (cmd, " "); 473: } 474: strcat (cmd, "\n"); 475: 476: a->value = CopyString (cmd); 477: } 1.1.1.2 root 478: 1.1 root 479: /* 480: ============================================================================= 1.1.1.2 root 481: 1.1 root 482: COMMAND EXECUTION 1.1.1.2 root 483: 1.1 root 484: ============================================================================= 485: */ 1.1.1.2 root 486: 1.1 root 487: typedef struct cmd_function_s 488: { 489: struct cmd_function_s *next; 490: char *name; 491: xcommand_t function; 492: } cmd_function_t; 1.1.1.2 root 493: 494: 1.1 root 495: static int cmd_argc; 496: static char *cmd_argv[MAX_STRING_TOKENS]; 497: static char *cmd_null_string = ""; 498: static char cmd_args[MAX_STRING_CHARS]; 1.1.1.2 root 499: 1.1 root 500: static cmd_function_t *cmd_functions; // possible commands to execute 1.1.1.2 root 501: 1.1 root 502: /* 503: ============ 504: Cmd_Argc 505: ============ 506: */ 507: int Cmd_Argc (void) 508: { 509: return cmd_argc; 510: } 1.1.1.2 root 511: 1.1 root 512: /* 513: ============ 514: Cmd_Argv 515: ============ 516: */ 517: char *Cmd_Argv (int arg) 518: { 519: if ( (unsigned)arg >= cmd_argc ) 520: return cmd_null_string; 521: return cmd_argv[arg]; 522: } 1.1.1.2 root 523: 1.1 root 524: /* 525: ============ 526: Cmd_Args 1.1.1.2 root 527: 1.1 root 528: Returns a single string containing argv(1) to argv(argc()-1) 529: ============ 530: */ 531: char *Cmd_Args (void) 532: { 533: return cmd_args; 534: } 1.1.1.2 root 535: 536: 1.1 root 537: /* 538: ====================== 539: Cmd_MacroExpandString 540: ====================== 541: */ 542: char *Cmd_MacroExpandString (char *text) 543: { 544: int i, j, count, len; 545: qboolean inquote; 546: char *scan; 547: static char expanded[MAX_STRING_CHARS]; 548: char temporary[MAX_STRING_CHARS]; 549: char *token, *start; 550: 551: inquote = false; 552: scan = text; 553: 554: len = strlen (scan); 555: if (len >= MAX_STRING_CHARS) 556: { 557: Com_Printf ("Line exceeded %i chars, discarded.\n", MAX_STRING_CHARS); 558: return NULL; 559: } 560: 561: count = 0; 562: 563: for (i=0 ; i<len ; i++) 564: { 565: if (scan[i] == '"') 566: inquote ^= 1; 567: if (inquote) 568: continue; // don't expand inside quotes 569: if (scan[i] != '$') 570: continue; 571: // scan out the complete macro 572: start = scan+i+1; 573: token = COM_Parse (&start); 574: if (!start) 575: continue; 576: 577: token = Cvar_VariableString (token); 578: 579: j = strlen(token); 580: len += j; 581: if (len >= MAX_STRING_CHARS) 582: { 583: Com_Printf ("Expanded line exceeded %i chars, discarded.\n", MAX_STRING_CHARS); 584: return NULL; 585: } 586: 587: strncpy (temporary, scan, i); 588: strcpy (temporary+i, token); 589: strcpy (temporary+i+j, start); 590: 591: strcpy (expanded, temporary); 592: scan = expanded; 593: i--; 594: 595: if (++count == 100) 596: { 597: Com_Printf ("Macro expansion loop, discarded.\n"); 598: return NULL; 599: } 600: } 601: 602: if (inquote) 603: { 604: Com_Printf ("Line has unmatched quote, discarded.\n"); 605: return NULL; 606: } 607: 608: return scan; 609: } 610: 611: 612: /* 613: ============ 614: Cmd_TokenizeString 1.1.1.2 root 615: 1.1 root 616: Parses the given string into command line tokens. 617: $Cvars will be expanded unless they are in a quoted token 618: ============ 619: */ 620: void Cmd_TokenizeString (char *text, qboolean macroExpand) 621: { 622: int i; 623: char *com_token; 1.1.1.2 root 624: 1.1 root 625: // clear the args from the last string 626: for (i=0 ; i<cmd_argc ; i++) 627: Z_Free (cmd_argv[i]); 628: 629: cmd_argc = 0; 630: cmd_args[0] = 0; 631: 632: // macro expand the text 633: if (macroExpand) 634: text = Cmd_MacroExpandString (text); 635: if (!text) 636: return; 1.1.1.2 root 637: 1.1 root 638: while (1) 639: { 640: // skip whitespace up to a /n 641: while (*text && *text <= ' ' && *text != '\n') 642: { 643: text++; 644: } 645: 646: if (*text == '\n') 647: { // a newline seperates commands in the buffer 648: text++; 649: break; 650: } 1.1.1.2 root 651: 1.1 root 652: if (!*text) 653: return; 654: 655: // set cmd_args to everything after the first arg 656: if (cmd_argc == 1) 657: { 658: int l; 659: 660: strcpy (cmd_args, text); 661: 662: // strip off any trailing whitespace 663: l = strlen(cmd_args) - 1; 664: for ( ; l >= 0 ; l--) 665: if (cmd_args[l] <= ' ') 666: cmd_args[l] = 0; 667: else 668: break; 669: } 670: 671: com_token = COM_Parse (&text); 672: if (!text) 673: return; 1.1.1.2 root 674: 1.1 root 675: if (cmd_argc < MAX_STRING_TOKENS) 676: { 677: cmd_argv[cmd_argc] = Z_Malloc (strlen(com_token)+1); 678: strcpy (cmd_argv[cmd_argc], com_token); 679: cmd_argc++; 680: } 681: } 682: 683: } 1.1.1.2 root 684: 685: 1.1 root 686: /* 687: ============ 688: Cmd_AddCommand 689: ============ 690: */ 691: void Cmd_AddCommand (char *cmd_name, xcommand_t function) 692: { 693: cmd_function_t *cmd; 694: 695: // fail if the command is a variable name 696: if (Cvar_VariableString(cmd_name)[0]) 697: { 698: Com_Printf ("Cmd_AddCommand: %s already defined as a var\n", cmd_name); 699: return; 700: } 701: 702: // fail if the command already exists 703: for (cmd=cmd_functions ; cmd ; cmd=cmd->next) 704: { 705: if (!strcmp (cmd_name, cmd->name)) 706: { 707: Com_Printf ("Cmd_AddCommand: %s already defined\n", cmd_name); 708: return; 709: } 710: } 1.1.1.2 root 711: 1.1 root 712: cmd = Z_Malloc (sizeof(cmd_function_t)); 713: cmd->name = cmd_name; 714: cmd->function = function; 715: cmd->next = cmd_functions; 716: cmd_functions = cmd; 717: } 1.1.1.2 root 718: 1.1 root 719: /* 720: ============ 721: Cmd_RemoveCommand 722: ============ 723: */ 724: void Cmd_RemoveCommand (char *cmd_name) 725: { 726: cmd_function_t *cmd, **back; 1.1.1.2 root 727: 1.1 root 728: back = &cmd_functions; 729: while (1) 730: { 731: cmd = *back; 732: if (!cmd) 733: { 734: Com_Printf ("Cmd_RemoveCommand: %s not added\n", cmd_name); 735: return; 736: } 737: if (!strcmp (cmd_name, cmd->name)) 738: { 739: *back = cmd->next; 740: Z_Free (cmd); 741: return; 742: } 743: back = &cmd->next; 744: } 745: } 1.1.1.2 root 746: 1.1 root 747: /* 748: ============ 749: Cmd_Exists 750: ============ 751: */ 752: qboolean Cmd_Exists (char *cmd_name) 753: { 754: cmd_function_t *cmd; 1.1.1.2 root 755: 1.1 root 756: for (cmd=cmd_functions ; cmd ; cmd=cmd->next) 757: { 758: if (!strcmp (cmd_name,cmd->name)) 759: return true; 760: } 1.1.1.2 root 761: 1.1 root 762: return false; 763: } 1.1.1.2 root 764: 765: 766: 1.1 root 767: /* 768: ============ 769: Cmd_CompleteCommand 770: ============ 771: */ 772: char *Cmd_CompleteCommand (char *partial) 773: { 774: cmd_function_t *cmd; 775: int len; 776: cmdalias_t *a; 777: 778: len = strlen(partial); 779: 780: if (!len) 781: return NULL; 782: 783: // check for exact match 784: for (cmd=cmd_functions ; cmd ; cmd=cmd->next) 785: if (!strcmp (partial,cmd->name)) 786: return cmd->name; 787: for (a=cmd_alias ; a ; a=a->next) 788: if (!strcmp (partial, a->name)) 789: return a->name; 1.1.1.2 root 790: 1.1 root 791: // check for partial match 792: for (cmd=cmd_functions ; cmd ; cmd=cmd->next) 793: if (!strncmp (partial,cmd->name, len)) 794: return cmd->name; 795: for (a=cmd_alias ; a ; a=a->next) 796: if (!strncmp (partial, a->name, len)) 797: return a->name; 1.1.1.2 root 798: 1.1 root 799: return NULL; 800: } 1.1.1.2 root 801: 802: 1.1 root 803: /* 804: ============ 805: Cmd_ExecuteString 1.1.1.2 root 806: 1.1 root 807: A complete command line has been parsed, so try to execute it 808: FIXME: lookupnoadd the token to speed search? 809: ============ 810: */ 811: void Cmd_ExecuteString (char *text) 812: { 813: cmd_function_t *cmd; 814: cmdalias_t *a; 1.1.1.2 root 815: 1.1 root 816: Cmd_TokenizeString (text, true); 817: 818: // execute the command line 819: if (!Cmd_Argc()) 820: return; // no tokens 1.1.1.2 root 821: 1.1 root 822: // check functions 823: for (cmd=cmd_functions ; cmd ; cmd=cmd->next) 824: { 825: if (!Q_strcasecmp (cmd_argv[0],cmd->name)) 826: { 827: if (!cmd->function) 828: { // forward to server command 829: Cmd_ExecuteString (va("cmd %s", text)); 830: } 831: else 832: cmd->function (); 833: return; 834: } 835: } 1.1.1.2 root 836: 1.1 root 837: // check alias 838: for (a=cmd_alias ; a ; a=a->next) 839: { 840: if (!Q_strcasecmp (cmd_argv[0], a->name)) 841: { 842: if (++alias_count == ALIAS_LOOP_COUNT) 843: { 844: Com_Printf ("ALIAS_LOOP_COUNT\n"); 845: return; 846: } 847: Cbuf_InsertText (a->value); 848: return; 849: } 850: } 851: 852: // check cvars 853: if (Cvar_Command ()) 854: return; 855: 856: // send it as a server command if we are connected 857: Cmd_ForwardToServer (); 858: } 1.1.1.2 root 859: 1.1 root 860: /* 861: ============ 862: Cmd_List_f 863: ============ 864: */ 865: void Cmd_List_f (void) 866: { 867: cmd_function_t *cmd; 868: int i; 1.1.1.2 root 869: 1.1 root 870: i = 0; 871: for (cmd=cmd_functions ; cmd ; cmd=cmd->next, i++) 872: Com_Printf ("%s\n", cmd->name); 873: Com_Printf ("%i commands\n", i); 874: } 1.1.1.2 root 875: 1.1 root 876: /* 877: ============ 878: Cmd_Init 879: ============ 880: */ 881: void Cmd_Init (void) 882: { 883: // 884: // register our commands 885: // 886: Cmd_AddCommand ("cmdlist",Cmd_List_f); 887: Cmd_AddCommand ("exec",Cmd_Exec_f); 888: Cmd_AddCommand ("echo",Cmd_Echo_f); 889: Cmd_AddCommand ("alias",Cmd_Alias_f); 890: Cmd_AddCommand ("wait", Cmd_Wait_f); 891: } 1.1.1.2 root 892:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.