/* Calisto (c) 1998-2000 Peter Howkins, Matthew Howkins, Simon Howkins $Id: commands.c,v 1.32 2000/03/12 00:58:01 peter Exp $ */ static char rcsid[] = "$Id: commands.c,v 1.32 2000/03/12 00:58:01 peter Exp $"; #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "unistd.h" #include "config.h" #include "colours.h" #include "commands.h" #include "globals.h" #include "help.h" #include "library.h" #include "log.h" #include "msnprintf.h" #include "playerdb.h" #include "privs.h" #include "structs.h" #include "strplus.h" typedef struct { const char *name; const char *shortcut; void (*function)(character *, char *); const char *privname; } command; void command_bug(character *, char *); void command_cls(character *, char *); void command_commands(character *, char *); void command_dc(character *, char *); void command_emote(character *, char *); void command_finger(character *, char *); void command_grant(character *, char *); void command_group(character *, char *); void command_idea(character *, char *); void command_lsd(character *, char *); void command_motd(character *, char *); void command_ping(character *, char *); void command_prompt(character *, char *); void command_quit(character *, char *); void command_recap(character *, char *); void command_reload(character *, char *); void command_remote(character *, char *); void command_remove(character *, char *); void command_save(character *, char *); void command_say(character *, char *); void command_set(character *, char *); void command_shout(character *, char *); void command_shutdown(character *, char *); void command_stat(character *, char *); void command_sumotd(character *, char *); void command_tell(character *, char *); void command_time(character *, char *); void command_typo(character *, char *); void command_users(character *, char *); void command_version(character *, char *); void command_who(character *, char *); void command_whoami(character *, char *); const command commands[] = { { "bug", "", command_bug, "n_base" }, { "bump", "", command_dc, "s_bump" }, { "clear", "", command_cls, "n_base" }, { "cls", "", command_cls, "n_base" }, { "commands","", command_commands, "n_base" }, { "dc", "", command_dc, "s_bump" }, { "emote", ";:",command_emote, "n_talk" }, { "exit", "", command_quit, "n_base" }, { "finger", "", command_finger, "n_base" }, { "grant", "", command_grant, "a_grant" }, { "group", "", command_group, "n_base" }, { "help", "", command_help, "n_base" }, /* Found in help.c */ { "idea", "", command_idea, "n_base" }, { "lsd", "", command_lsd, "s_trace" }, { "motd", "", command_motd, "n_base" }, { "ping", "", command_ping, "n_base" }, { "prompt", "", command_prompt, "n_base" }, { "quit", "", command_quit, "n_base" }, { "recap", "", command_recap, "n_base" }, { "reload", "", command_reload, "a_base" }, { "remote", ",", command_remote, "n_talk" }, { "remove", "", command_remove, "a_grant" }, { "save", "", command_save, "n_save" }, { "say", "'", command_say, "n_talk" }, { "set", "", command_set, "a_base" }, { "shout", "", command_shout, "n_talk" }, { "shutdown","", command_shutdown, "a_shutdown" }, { "stat", "", command_stat, "a_base" }, { "sumotd", "", command_sumotd, "s_base" }, { "tell", ".", command_tell, "n_talk" }, { "time", "", command_time, "n_base" }, { "typo", "", command_typo, "n_base" }, { "users", "", command_users, "n_base" }, { "version", "", command_version, "n_base" }, { "who", "", command_who, "n_base" }, { "whoami", "", command_whoami, "n_base" }, { "x", "", command_finger, "n_base" } }; const unsigned commandn = sizeof commands / sizeof(command); void command_version(character *c, char *r) { descriptor *des = getdes(c); bar2(des, "Version", NULL, NULL); send_to_char(c, "^PCalisto^n %u.%02u (c) 1998-2000 ^YFlibble^n, ^YThe_Pope^n and ^YWilfred^n\n", version/100, version%100); send_to_char(c, " ^G+^n Colour Code ^G-^n ^YEkto^n (ekto@ekto.org)\n"); send_to_char(c, " ^G+^n snprintf ^G-^n based on code by ^YAlain Magloire^n (alainm@rcsm.ee.mcgill.ca)\n"); bar2(des, NULL, NULL, NULL); } void command_set(character *c, char *r) { char *variable; char *value; bool quoted = FALSE; if (STREQ(r, "")) { send_to_char(c, "use_net_lookups: %d\n", use_net_lookups); send_to_char(c, "idle_boot_time: %u minutes\n", idle_boot_time); send_to_char(c, "max_connections: %u\n", max_connections); return; } /* Break input into variable and value */ strmunch(r, &variable, &r); if (*r == '\"') { quoted = TRUE; r++; } value = r; if (quoted) { while (*r && *r != '\"') r++; } else { while (*r && !isspace(*r)) r++; } *r = '\0'; /* send_to_char(c, "variable = \'%s\'\n", variable); send_to_char(c, "value = \'%s\'\n", value);*/ /* Check if value specified OK */ if (STREQ(value, "")) { help_usage(c, "set"); return; } /* Handle known variables, and complain about unknown ones */ if (STRIEQ(variable, "use_net_lookups")) { use_net_lookups = atoi(value); if (use_net_lookups) use_net_lookups = TRUE; } else if (STRIEQ(variable, "idle_boot_time")) { idle_boot_time = (unsigned) atoi(value); } else if (STRIEQ(variable, "max_connections")) { max_connections = (unsigned) atoi(value); } else { send_to_char(c, "Unknown variable '%s'\n" "Use the set command without parameters to list variables.\n", variable); } } void command_recap(character *c, char *r) { if(STREQ(r, "")) { help_usage(c, "recap"); return; } if(STRIEQ(r, c->name)) { STRNCOPY(c->name, r, sizeof(c->name)); send_to_char(c, "Name recapitalised\n"); } else { send_to_char(c, "Input must be the same as your name\n"); } } void command_save(character *c, char *r) { int error = save_player(c, c->name); if(error) { send_to_char(c, "Error saving your character\n"); } else { send_to_char(c, "Successfully saved your character\n"); } } void command_sumotd(character *c, char *r) { descriptor *des = getdes(c); bar2(des, "Super-user Message Of The Day", NULL, NULL); send_file_to_descriptor("lib/etc/sumotd", des); bar2(des, NULL, NULL, NULL); } void command_cls(character *c, char *r) { descriptor *des = getdes(c); int i; for (i = 0; i < des->term_height; i++) { send_to_char(c, "\n"); } /* send_to_char(c, "\x1b[0;0H"); */ send_to_char(c, "\x1b[%dA", des->term_height); } void command_reload(character *c, char *r) { if (STRIEQ(r, "help")) { help_reload(c); } else if (STRIEQ(r, "all")) { help_reload(c); } else { send_to_char(c, "Unrecognised reload option %s\n", r); } } #define COMMAND_STAT_OPTIONS "net mem" static void command_stat_usage(character *c) { send_to_char(c, "Usage: stat <option> [<option>...]\n"); send_to_char(c, "where <option> is one of `%s all`\n", COMMAND_STAT_OPTIONS); } void command_stat(character *c, char *r) { if (*r) { while (*r) { char *sub; strmunch(r, &sub, &r); if (STRIEQ(sub, "mem")) { pool_stat_t ps = pool_stat(descriptor_pool); send_to_char(c, "^H[Memory - Descriptors]^n\n"); send_to_char(c, " Block Size : %u\n", ps.block_size); send_to_char(c, " Usage : %u\n", ps.usage); send_to_char(c, " Capacity : %u (%.1fk)\n", ps.capacity, (double) (ps.block_size * ps.capacity) / 1024.0); send_to_char(c, " Free : %u\n", ps.capacity - ps.usage); send_to_char(c, " Connections : %u/%u\n", ps.usage, max_connections); } else if (STRIEQ(sub, "net")) { FILE *f; const char *hostname = getenv("HOSTNAME"); const char *machtype = getenv("MACHTYPE"); send_to_char(c, "^H[Network and Machine]^n\n"); send_to_char(c, " PID : %u\n", (unsigned) getpid()); send_to_char(c, " PPID : %u\n", (unsigned) getppid()); send_to_char(c, " HOST : %s\n", hostname ? hostname : "** Unknown **"); send_to_char(c, " TYPE : %s\n", machtype ? machtype : "** Unknown **"); /* Display load average of server, if available */ f = fopen("/proc/loadavg", "r"); if (f) { char buffer[256]; float load1, load5, load15; if (fgets(buffer, sizeof(buffer), f)) { if (sscanf(buffer, "%f %f %f", &load1, &load5, &load15) == 3) { send_to_char(c, "LoadAvg : %.2f %.2f %.2f\n", load1, load5, load15); } } fclose(f); } } else if (STRIEQ(sub, "all")) { char all[] = COMMAND_STAT_OPTIONS; command_stat(c, all); } else { send_to_char(c, "Unknown stat option `%s`\n", sub); command_stat_usage(c); } } } else { command_stat_usage(c); } #undef COMMAND_STAT_OPTIONS } void command_finger(character *c, char *r) { /* formats finger - does a finger on the character that called func finger bob - does a finger on bob check for r = "" r logged in r not logged in and exists r not logged in and doesn't exist */ time_t now; descriptor *des = getdes(c); descriptor *victdes; character *victim; character target; char buffer[OUTPUT_BUFFER]; bool loggedin = FALSE; if(STREQ(r, "")) { victim = c; loggedin = TRUE; } else { if((victim = character_from_name(r)) != NULL) { /* victim is logged on and found */ loggedin = TRUE; } else { /* check to see is r is in the players directory, if so load else return */ int failed; failed = load_player(&target, r); if (failed) { send_to_char(c, "Player %s, not found\n", r); return; } else { victim = ⌖ loggedin = FALSE; } } } now = time(NULL); victdes = getdes(victim); if (loggedin) { seconds_to_string(victim->prevtime + difftime(now, victim->logintime), buffer, sizeof(buffer)); } else { seconds_to_string(victim->prevtime, buffer, sizeof(buffer)); } bar2(des, "Finger", NULL, NULL); send_to_char(c, " Name: %s\n", victim->name); send_to_char(c, "Total Time: %s\n", buffer); /* Display privileges */ if (victim == c || haspriv(c, "s_base")) { send_to_char(c, " Privs:"); privs_list_player(c, victim); send_to_char(c, "^n\n"); } if (loggedin) { send_to_char(c, " Group: %s\n", victim->group); send_to_char(c, " Termtype: %s (%ux%u)\n", victdes->termtype, victdes->term_width, victdes->term_height); if (haspriv(c, "s_trace")) { send_to_char(c, " Host: %s\n", victdes->hostname); } } bar2(des, NULL, NULL, NULL); } void command_group(character *c, char *r) { char groupname[MAX_GROUP_NAME_LENGTH+1]; stripCodes(groupname, r); if(STREQ(r, "")) { STRNCOPY(groupname, "Public", sizeof(groupname)); } if (strlen(r) > MAX_GROUP_NAME_LENGTH) { send_to_char(c, "Group name too long (max %d)\n", MAX_GROUP_NAME_LENGTH); return; } strlower(groupname); groupname[0] = toupper(groupname[0]); if (!STREQ(groupname, c->group)) { /* Announce departure of character from old group */ send_to_room_except(c->group, c, "\n+++ %s joins group %s\n", c->name, groupname); STRNCOPY(c->group, groupname, sizeof(c->group)); /* annouce arrival in new group */ send_to_char(c, "+++ You have joined group ^y%s^n\n", c->group); send_to_room_except(c->group, c, "\n+++ %s joins this group\n", c->name); } else { send_to_char(c, "You are already in group ^y%s^n\n", c->group); } } void command_dc(character *c, char *r) { descriptor *des = NULL; character *ch; if (STREQ(r, "")) { help_usage(c, "bump/dc"); return; } ch = character_from_name(r); if (ch) { /* found character, drop em */ des = getdes(ch); } else { /* char name not found - assume a number */ if (!strisdigit(r)) { /* Not a number - report bad character name */ send_to_char(c, "Character %s not known\n", r); return; } else { int sfd = atoi(r); listnode *dNode = AllConns.head.next; while (LIST_NODE_IS_REAL(dNode)) { descriptor *des2 = LIST_GET_DATA(dNode, descriptor *, descriptorlink); if (sfd == des2->sfd) { des = des2; break; } dNode = dNode->next; } if (!des) { send_to_char(c, "SFD %d not found\n", sfd); return; } } } /* Before we drop, check we are not dropping ourselves */ if (des == getdes(c)) { send_to_char(c, "Haven't you heard of the quit command?\n"); return; } des->state = STATE_CLOSING; if (des->player.loggedin) { send_to_all_except(&des->player, "\n+++ ^r%s^n has logged out\n", des->player.name); } } void command_time(character *c, char *r) { time_t now; struct tm nowtm; char buff[OUTPUT_BUFFER]; unsigned long howlong; now = time(NULL); nowtm = *localtime(&now); strftime(buff, sizeof(buff), "%a %b %d %H:%M:%S %Y", &nowtm); send_to_char(c, "^WCurrent : %s\n^n", buff); nowtm = *localtime(&starttime); strftime(buff, sizeof(buff), "%a %b %d %H:%M:%S %Y", &nowtm); send_to_char(c, "Up Since : %s\n", buff); howlong = (unsigned long) difftime(now, starttime); seconds_to_string(howlong, buff, sizeof(buff)); send_to_char(c, "Up Time : %s\n", buff); } void command_ping(character *c, char *r) { character *target; if (STREQ(r, "")) { help_usage(c, "ping"); } else { target = character_from_name(r); if (target == NULL) { send_to_char(c, "%s not found\n", r); } else { send_to_char(target, "\a^YPING\n^n%s is trying to contact you\n", c->name); } } } void command_remove(character *c, char *r) { if (STREQ(r, "")) { help_usage(c, "remove"); return; } { character *target; char *privname = r; strmunch(r, &r, &privname); /* r should now be player name, privname should be the priv */ /* try to find player, if not found bail out of function */ target = character_from_name(r); if (!target) { send_to_char(c, "Player %s not found\n", r); help_usage(c, "remove"); return; } /* check if removing privs from oneself */ if (c == target) { send_to_char(c, "You may not remove your own privs\n"); return; } /* if privname is blank print out usage and bail out */ if (STREQ(privname, "")) { send_to_char(c, "Unknown priv\n"); help_usage(c, "remove"); return; } /* search through the priv list and try to find the priv */ if (privname_exists(privname)) { send_to_char(c, "You have removed from %s the %s priv.\n", target->name, privname); send_to_char(target, "You have lost the %s priv\n", privname); clearpriv(target, privname); } else { send_to_char(c, "Priv %s not found\n", privname); help_usage(c, "remove"); } } } static void command_grant_usage(character *c) { help_usage(c, "grant"); send_to_char(c, "Available privs:\n"); privs_list_all(c); send_to_char(c, "\n"); } void command_grant(character *c, char *r) { if (STREQ(r, "")) { command_grant_usage(c); return; } { character *target; char *privname = r; strmunch(r, &r, &privname); /* r should now be player name, privname should be the priv */ /* if privname is blank print out usage and bail out */ if (STREQ(privname, "")) { command_grant_usage(c); return; } /* try to find player, if not found bail out of function */ target = character_from_name(r); if (!target) { send_to_char(c, "Player %s not found\n", r); command_grant_usage(c); return; } /* search through the priv list and try to find the priv */ if (privname_exists(privname)) { send_to_char(c, "You have granted %s the %s priv.\n", target->name, privname); send_to_char(target, "You have been granted the %s priv\n", privname); setpriv(target, privname); } else { send_to_char(c, "Priv %s not found\n", privname); command_grant_usage(c); } } } void command_lsd(character *c, char *r) { listnode *dNode = AllConns.head.next; descriptor *des2; unsigned long howlong; time_t now; des2 = getdes(c); bar2(des2, "Sockets connected and states", NULL, NULL); send_to_char(c, "^YSFD State (name) (login) Idle Host^n\n\n"); while (LIST_NODE_IS_REAL(dNode)) { descriptor *des = LIST_GET_DATA(dNode, descriptor *, descriptorlink); character *c2 = &des->player; char *state = ""; send_to_char(c, "%.3d ", des->sfd); switch (des->state) { case STATE_LOGIN: state = "LOGIN"; break; case STATE_NEW1: state = "NEW1"; break; case STATE_NEW2: state = "NEW2"; break; case STATE_NEW3: state = "NEW3"; break; case STATE_PASSWORD: state = "PASSWORD"; break; case STATE_PLAY: state = "PLAY"; break; case STATE_CLOSING: state = "CLOSING"; break; } send_to_char(c, "%-9s", state); now = time(NULL); if (des->state == STATE_PLAY) { send_to_char(c, "%-13s", c2->name); /* login Time */ howlong = (unsigned long) difftime(now, c2->logintime); send_to_char(c, " %02lu:", howlong / 3600); howlong %= 3600; send_to_char(c, "%02lu:", howlong / 60); howlong %= 60; send_to_char(c, "%02lu", howlong); } else { send_to_char(c, " "); } /* Idle Time */ howlong = (unsigned long) difftime(now, des->idletime); send_to_char(c, " %02lu:", howlong / 60); howlong %= 60; send_to_char(c, "%02lu %s\n", howlong, des->hostname); dNode = dNode->next; } bar2(des2, NULL, NULL, NULL); } void command_bug(character *c, char *r) { if (STREQ(r, "")) { help_usage(c, "bug"); } else { log(bug, "%s - %s", c->name, r); send_to_char(c, "Thank you, the bug has been recorded\n"); } } void command_idea(character *c, char *r) { if (STREQ(r, "")) { help_usage(c, "idea"); } else { log(idea, "%s - %s", c->name, r); send_to_char(c, "Thank you, your idea has been recorded\n"); } } void command_typo(character *c, char *r) { if (STREQ(r, "")) { help_usage(c, "typo"); } else { log(typo, "%s - %s", c->name, r); send_to_char(c, "Thank you, the typo has been recorded\n"); } } void command_shutdown(character *c, char *r) { sdown = TRUE; } void command_motd(character *c, char *r) { descriptor *des = getdes(c); bar2(des, "Message Of The Day", NULL, NULL); send_file_to_descriptor("lib/etc/motd", des); bar2(des, NULL, NULL, NULL); } void command_prompt(character *c, char *r) { if(strlen(r) > MAX_PROMPT_LENGTH-2) { send_to_char(c, "Prompt too long (max %d)\n", MAX_PROMPT_LENGTH-2); } else { STRNCOPY(c->prompt, r, sizeof(c->prompt)); } } void command_commands(character *c, char *r) { descriptor *des = getdes(c); int i; bar2(des, "List of commands", NULL, NULL); for(i = 0;i < commandn;i++) { if(haspriv(c, commands[i].privname)) send_to_char(c, "%s%s^n ", privcol(commands[i].privname), commands[i].name); } send_to_char(c, "\n"); bar2(des, NULL, NULL, NULL); } void command_users(character *c, char *r) { listnode *pNode = AllPlayers.head.next; while (LIST_NODE_IS_REAL(pNode)) { character *pChar = LIST_GET_DATA(pNode,character *, characterlink); send_to_char(c, "%s ", pChar->name); pNode = pNode->next; } send_to_char(c, "\n"); } void command_who(character *c, char *r) { descriptor *des = getdes(c); listnode *pNode = AllPlayers.head.next; int howmany = 0; time_t now; unsigned long howlong; now = time(NULL); bar2(des, "Who is logged on?", NULL, NULL); send_to_char(c, "^Y%-*s Login Idle %-*s ", MAX_NAME_LENGTH, "Name", MAX_GROUP_NAME_LENGTH, "Group"); if(haspriv(c, "s_trace")) { send_to_char(c, "Host"); } send_to_char(c, "^n\n"); while (LIST_NODE_IS_REAL(pNode)) { character *pChar = LIST_GET_DATA(pNode, character *, characterlink); descriptor *des = LIST_GET_DATA(pChar, descriptor *, player); /* Display name */ send_to_char(c, "%-*s", MAX_NAME_LENGTH, pChar->name); /* Calculate how long they have been logged in */ howlong = (unsigned long) difftime(now, pChar->logintime); send_to_char(c, " %02lu:", howlong / 3600); howlong %= 3600; send_to_char(c, "%02lu:", howlong / 60); howlong %= 60; send_to_char(c, "%02lu", howlong); /* Calculate how long they have been idle for */ howlong = (unsigned long) difftime(now, des->idletime); send_to_char(c, " %02lu:", howlong / 60); howlong %= 60; send_to_char(c, "%02lu ", howlong); send_to_char(c, "%-*s ", MAX_GROUP_NAME_LENGTH, pChar->group); if(haspriv(c, "s_trace")) { send_to_char(c, "%s", des->hostname); } send_to_char(c, "\n"); pNode = pNode->next; howmany++; } send_to_char(c, "Total: %d user%s\n", howmany, howmany != 1 ? "s" : ""); bar2(des, NULL, NULL, NULL); } void command_tell(character *c, char *sRemainder) { char *sMessage = sRemainder; char *sTerm; while (*sMessage && !isspace(*sMessage)) sMessage++; sTerm = sMessage; while (*sMessage && isspace(*sMessage)) sMessage++; *sTerm = 0; { character *pDest = character_from_name(sRemainder); if (!pDest) { send_to_char(c, "Character '%s' could not be found or is ambiguous.\n", sRemainder); return; } if (pDest == c) { send_to_char(c, "Talking to yourself again?\n"); return; } if(STREQ(sMessage, "")) { send_to_char(c, "Tell %s, what ?\n", pDest->name); return; } send_to_char(pDest, "^W> %s tells you '%s^W'^n\n", c->name, sMessage); send_to_char(c, "You tell %s '%s^n'\n", pDest->name, sMessage); } } void command_remote(character *c, char *sRemainder) { char *sMessage = sRemainder; char *sTerm; while (*sMessage && !isspace(*sMessage)) sMessage++; sTerm = sMessage; while (*sMessage && isspace(*sMessage)) sMessage++; *sTerm = 0; { character *pDest = character_from_name(sRemainder); if (!pDest) { send_to_char(c, "Character '%s' could not be found or is ambiguous.\n", sRemainder); return; } if (pDest == c) { send_to_char(c, "Thats you, you fool\n"); return; } if(STREQ(sMessage, "")) { send_to_char(c, "Emote to %s, what ?\n", pDest->name); return; } send_to_char(pDest, "^W> %s %s^W, at you^n\n", c->name, sMessage); send_to_char(c, "You emote '%s %s^n' to %s^n\n", c->name, sMessage, pDest->name); } } void command_say(character *c, char *r) { if (STREQ(r, "")) { help_usage(c, "say"); return; } send_to_room_except(c->group, c, "%s says \'%s^n\'\n", c->name, r); send_to_char(c, "You say \'%s^n\'\n", r); } void command_emote(character *c, char *r) { if (STREQ(r, "")) { help_usage(c, "emote"); return; } send_to_room_except(c->group, c, "%s %s\n", c->name, r); send_to_char(c, "You emote \'%s %s\'\n", c->name, r); } void command_shout(character *c, char *r) { if (STREQ(r, "")) { help_usage(c, "shout"); return; } send_to_all_except(c, "%s shouts \'%s^n\'\n", c->name, r); send_to_char(c, "You shout \'%s^n\'\n", r); } void command_quit(character *c, char *r) { descriptor *des = getdes(c); des->state = STATE_CLOSING; send_to_all_except(c, "\n+++ ^r%s^n has logged out\n", c->name); send_to_char(c, "\n+++ You have logged out\n"); if (send_file_to_descriptor("lib/etc/logout", des) !=0) send_to_descriptor(des, "Goodbye!\n"); des->safe = FALSE; } void command_whoami(character *c, char *r) { send_to_char(c, "You are ^r%s^n\n", c->name); } bool command_shortcut_run(descriptor *des, char *s) { character *p = &des->player; int c; s = strip_leading_white_space(s); if (strlen(s) != 0) { for (c = 0; c < commandn; c++) { if (strchr(commands[c].shortcut, s[0]) && haspriv(p, commands[c].privname)) { void (*function)(character *, char *); function = commands[c].function; s++; /* to get past the shortcut character */ s = strip_leading_white_space(s); function(p, s); return TRUE; } } } return FALSE; } void command_parse_n_run(descriptor *des, const char *first, char *remainder) { unsigned int count = 0; unsigned int index = 0; unsigned int c; character *p = &des->player; if (STREQ(first, "")) return; for (c = 0; c < commandn; c++) { if (STREQ(first, commands[c].name) && haspriv(p, commands[c].privname)) { /* Matches exactly */ void (*function)(character *, char *); function = commands[c].function; function(p, remainder); return; } else if (STRNEQ(first, commands[c].name, strlen(first)) && haspriv(p, commands[c].privname)) { /* Part matches */ index = c; count ++; } } switch (count) { case 0: send_to_char(p, "Command \'%s\' not known, try help\n", first); break; case 1: /* Matches one command without ambiguity */ { void (*function)(character *, char *); function = commands[index].function; function(p, remainder); return; break; } default: /* Part matches more than one command */ send_to_char(p, "Command \'%s\' ambiguous, try help\n", first); break; } } void command_do(descriptor *des, const char *buffer) { char line[MAX_RAW_INPUT_BUFFER]; char *first, *remainder; char *temp; bool carryon = TRUE; STRNCOPY(line, buffer, sizeof(line)); first = line; while (carryon == TRUE) { /* strip leading white space in command */ first = strip_leading_white_space(first); /* search for a ; in the input */ temp = strchr(first+1, ';'); if (temp != NULL) { /* found a ; */ *temp = '\0'; temp++; if (*temp == '\0') { /* is temp a 0 length string ? */ carryon = FALSE; } else { carryon = TRUE; } } else { carryon = FALSE; } strip_trailing_white_space(first); if (command_shortcut_run(des, first) == FALSE) { strmunch(first, &first, &remainder); strlower(first); command_parse_n_run(des, first, remainder); } if (carryon == TRUE) { first = temp; } } /* Do a prompt */ send_to_char(&des->player, "%s^n", &des->player.prompt); } descriptor* getdes(character *c) { return LIST_GET_DATA(c, descriptor *, player); } void seconds_to_string(unsigned long seconds, char *buffer, size_t size) { unsigned long t; int len; t = seconds / (60 * 60 * 24); if (t > 0) { len = msnprintf(buffer, size, "%lu day%s, ", t, t != 1 ? "s" : ""); buffer += len; size -= len; } seconds %= (60 * 60 * 24); t = seconds / (60 * 60); if (t > 0) { len = msnprintf(buffer, size, "%lu hr%s, ", t, t != 1 ? "s" : ""); buffer += len; size -= len; } seconds %= (60 * 60); t = seconds / 60; if (t > 0) { len = msnprintf(buffer, size, "%lu min%s, ", t, t != 1 ? "s" : ""); buffer += len; size -= len; } seconds %= 60; msnprintf(buffer, size, "%lu sec%s", seconds, seconds != 1 ? "s": ""); }