00001
00002
00003
00004
00005
00006 #include "copyright.h"
00007 #include "autoconf.h"
00008 #include "config.h"
00009 #include "externs.h"
00010
00011 #include <signal.h>
00012
00013 #include "ansi.h"
00014 #include "attrs.h"
00015 #include "command.h"
00016 #include "interface.h"
00017 #include "powers.h"
00018 #ifdef REALITY_LVLS
00019 #include "levels.h"
00020 #endif
00021
00022 char * DCL_CDECL tprintf(const char *fmt,...)
00023 {
00024 static char buff[LBUF_SIZE];
00025 va_list ap;
00026 va_start(ap, fmt);
00027 mux_vsnprintf(buff, LBUF_SIZE, fmt, ap);
00028 va_end(ap);
00029 return buff;
00030 }
00031
00032 void DCL_CDECL safe_tprintf_str(char *str, char **bp, const char *fmt,...)
00033 {
00034 va_list ap;
00035 va_start(ap, fmt);
00036 size_t nAvailable = LBUF_SIZE - (*bp - str);
00037 size_t len = mux_vsnprintf(*bp, (int)nAvailable, fmt, ap);
00038 va_end(ap);
00039 *bp += len;
00040 }
00041
00042
00043
00044
00045
00046 dbref insert_first(dbref head, dbref thing)
00047 {
00048 s_Next(thing, head);
00049 return thing;
00050 }
00051
00052 dbref remove_first(dbref head, dbref thing)
00053 {
00054 if (head == thing)
00055 {
00056 return Next(thing);
00057 }
00058
00059 dbref prev;
00060
00061 DOLIST(prev, head)
00062 {
00063 if (Next(prev) == thing)
00064 {
00065 s_Next(prev, Next(thing));
00066 return head;
00067 }
00068 }
00069 return head;
00070 }
00071
00072
00073
00074
00075
00076 dbref reverse_list(dbref list)
00077 {
00078 dbref newlist, rest;
00079
00080 newlist = NOTHING;
00081 while (list != NOTHING)
00082 {
00083 rest = Next(list);
00084 s_Next(list, newlist);
00085 newlist = list;
00086 list = rest;
00087 }
00088 return newlist;
00089 }
00090
00091
00092
00093
00094
00095 bool member(dbref thing, dbref list)
00096 {
00097 DOLIST(list, list)
00098 {
00099 if (list == thing)
00100 {
00101 return true;
00102 }
00103 }
00104 return false;
00105 }
00106
00107 bool could_doit(dbref player, dbref thing, int locknum)
00108 {
00109 if (thing == HOME)
00110 {
00111 return true;
00112 }
00113
00114
00115
00116 if ( !isPlayer(player)
00117 && Key(thing))
00118 {
00119 return false;
00120 }
00121 if (Pass_Locks(player))
00122 {
00123 return true;
00124 }
00125
00126 dbref aowner;
00127 int aflags;
00128 char *key = atr_get(thing, locknum, &aowner, &aflags);
00129 bool doit = eval_boolexp_atr(player, thing, thing, key);
00130 free_lbuf(key);
00131 return doit;
00132 }
00133
00134 bool can_see(dbref player, dbref thing, bool can_see_loc)
00135 {
00136
00137
00138
00139
00140 if ( mudconf.dark_sleepers
00141 && isPlayer(thing)
00142 && !Connected(thing)
00143 && !Puppet(thing))
00144 {
00145 return false;
00146 }
00147
00148
00149
00150 if ( player == thing
00151 || isExit(thing))
00152 {
00153 return false;
00154 }
00155
00156
00157
00158
00159
00160
00161 if (can_see_loc)
00162 {
00163 #ifdef REALITY_LVLS
00164 return ((!Dark(thing) && IsReal(player, thing)) ||
00165 #else
00166 return (!Dark(thing) ||
00167 #endif
00168 (mudconf.see_own_dark && MyopicExam(player, thing)));
00169 }
00170 else
00171 {
00172 #ifdef REALITY_LVLS
00173 return ((Light(thing) && !Dark(thing) && IsReal(player, thing)) ||
00174 #else
00175 return ((Light(thing) && !Dark(thing)) ||
00176 #endif
00177 (mudconf.see_own_dark && MyopicExam(player, thing)));
00178 }
00179 }
00180
00181 static bool pay_quota(dbref who, int cost)
00182 {
00183
00184
00185 if (cost <= 0)
00186 {
00187 return true;
00188 }
00189
00190
00191
00192 dbref aowner;
00193 int aflags;
00194 char *quota_str = atr_get(Owner(who), A_RQUOTA, &aowner, &aflags);
00195 int quota = mux_atol(quota_str);
00196 free_lbuf(quota_str);
00197
00198
00199
00200 quota -= cost;
00201 if ( quota < 0
00202 && !Free_Quota(who)
00203 && !Free_Quota(Owner(who)))
00204 {
00205 return false;
00206 }
00207
00208
00209
00210 char buf[20];
00211 mux_ltoa(quota, buf);
00212 atr_add_raw(Owner(who), A_RQUOTA, buf);
00213
00214 return true;
00215 }
00216
00217 bool canpayfees(dbref player, dbref who, int pennies, int quota)
00218 {
00219 if ( !Wizard(who)
00220 && !Wizard(Owner(who))
00221 && !Free_Money(who)
00222 && !Free_Money(Owner(who))
00223 && (Pennies(Owner(who)) < pennies))
00224 {
00225 if (player == who)
00226 {
00227 notify(player, tprintf("Sorry, you don't have enough %s.",
00228 mudconf.many_coins));
00229 }
00230 else
00231 {
00232 notify(player, tprintf("Sorry, that player doesn't have enough %s.",
00233 mudconf.many_coins));
00234 }
00235 return false;
00236 }
00237 if (mudconf.quotas)
00238 {
00239 if (!pay_quota(who, quota))
00240 {
00241 if (player == who)
00242 {
00243 notify(player, "Sorry, your building contract has run out.");
00244 }
00245 else
00246 {
00247 notify(player,
00248 "Sorry, that player's building contract has run out.");
00249 }
00250 return false;
00251 }
00252 }
00253 payfor(who, pennies);
00254 return true;
00255 }
00256
00257 bool payfor(dbref who, int cost)
00258 {
00259 if ( Wizard(who)
00260 || Wizard(Owner(who))
00261 || Free_Money(who)
00262 || Free_Money(Owner(who)))
00263 {
00264 return true;
00265 }
00266 who = Owner(who);
00267 int tmp;
00268 if ((tmp = Pennies(who)) >= cost)
00269 {
00270 s_Pennies(who, tmp - cost);
00271 return true;
00272 }
00273 return false;
00274 }
00275
00276 void add_quota(dbref who, int payment)
00277 {
00278 dbref aowner;
00279 int aflags;
00280 char buf[20];
00281
00282 char *quota = atr_get(who, A_RQUOTA, &aowner, &aflags);
00283 mux_ltoa(mux_atol(quota) + payment, buf);
00284 free_lbuf(quota);
00285 atr_add_raw(who, A_RQUOTA, buf);
00286 }
00287
00288 void giveto(dbref who, int pennies)
00289 {
00290 if ( Wizard(who)
00291 || Wizard(Owner(who))
00292 || Free_Money(who)
00293 || Free_Money(Owner(who)))
00294 {
00295 return;
00296 }
00297 who = Owner(who);
00298 s_Pennies(who, Pennies(who) + pennies);
00299 }
00300
00301
00302
00303
00304
00305 char *MakeCanonicalObjectName(const char *pName, int *pnName, bool *pbValid)
00306 {
00307 static char Buf[MBUF_SIZE];
00308
00309 *pnName = 0;
00310 *pbValid = false;
00311
00312 if (!pName)
00313 {
00314 return NULL;
00315 }
00316
00317
00318
00319
00320 int nVisualWidth;
00321 int nBuf = ANSI_TruncateToField(pName, sizeof(Buf), Buf, MBUF_SIZE,
00322 &nVisualWidth, ANSI_ENDGOAL_NORMAL);
00323
00324
00325
00326
00327 if (nVisualWidth <= 0)
00328 {
00329 return NULL;
00330 }
00331
00332
00333
00334 size_t nStripped;
00335 char *pStripped = strip_ansi(Buf, &nStripped);
00336
00337
00338
00339
00340 if ( strchr("*!#", *pStripped)
00341 || mux_isspace(pStripped[0])
00342 || mux_isspace(pStripped[nStripped-1]))
00343 {
00344 return NULL;
00345 }
00346
00347
00348
00349
00350 for (unsigned int i = 0; i < nStripped; i++)
00351 {
00352 if (!mux_ObjectNameSet(pStripped[i]))
00353 {
00354 return NULL;
00355 }
00356 }
00357
00358
00359
00360 if ( (nStripped == 2 && memcmp("me", pStripped, 2) == 0)
00361 || (nStripped == 4 && ( memcmp("home", pStripped, 4) == 0
00362 || memcmp("here", pStripped, 4) == 0)))
00363 {
00364 return NULL;
00365 }
00366
00367 *pnName = nBuf;
00368 *pbValid = true;
00369 return Buf;
00370 }
00371
00372
00373
00374 char *MakeCanonicalExitName(const char *pName, int *pnName, bool *pbValid)
00375 {
00376 static char Buf[MBUF_SIZE];
00377 static char Out[MBUF_SIZE];
00378
00379 *pnName = 0;
00380 *pbValid = false;
00381
00382 if (!pName)
00383 {
00384 return NULL;
00385 }
00386
00387
00388
00389
00390 char *pStripped = strip_ansi(pName);
00391 char *pBuf = Buf;
00392 safe_mb_str(pStripped, Buf, &pBuf);
00393 *pBuf = '\0';
00394
00395 size_t nBuf = pBuf - Buf;
00396 pBuf = Buf;
00397
00398 bool bHaveDisplay = false;
00399
00400 char *pOut = Out;
00401
00402 for (; nBuf;)
00403 {
00404
00405
00406
00407 char *q = strchr(pBuf, ';');
00408 size_t n;
00409 if (q)
00410 {
00411 *q = '\0';
00412 n = q - pBuf;
00413 q = pBuf;
00414 pBuf += n + 1;
00415 nBuf -= n + 1;
00416 }
00417 else
00418 {
00419 n = nBuf;
00420 q = pBuf;
00421 pBuf += nBuf;
00422 nBuf = 0;
00423 }
00424
00425 if (bHaveDisplay)
00426 {
00427
00428
00429
00430
00431 int nN;
00432 bool bN;
00433 char *pN = MakeCanonicalObjectName(q, &nN, &bN);
00434 if ( bN
00435 && nN < MBUF_SIZE - (pOut - Out) - 1)
00436 {
00437 safe_mb_chr(';', Out, &pOut);
00438 safe_mb_str(pN, Out, &pOut);
00439 }
00440 }
00441 else
00442 {
00443
00444
00445
00446
00447
00448
00449 int vw;
00450 ANSI_TruncateToField(pName, sizeof(Out), Out, n, &vw,
00451 ANSI_ENDGOAL_NORMAL);
00452
00453
00454
00455 if ((size_t)vw == n)
00456 {
00457 int nN;
00458 bool bN;
00459 char *pN = MakeCanonicalObjectName(Out, &nN, &bN);
00460 if ( bN
00461 && nN <= MBUF_SIZE - 1)
00462 {
00463 safe_mb_str(pN, Out, &pOut);
00464 bHaveDisplay = true;
00465 }
00466 }
00467 }
00468 }
00469 if (bHaveDisplay)
00470 {
00471 *pnName = pOut - Out;
00472 *pbValid = true;
00473 *pOut = '\0';
00474 return Out;
00475 }
00476 else
00477 {
00478 return NULL;
00479 }
00480 }
00481
00482
00483
00484
00485
00486 bool ValidatePlayerName(const char *pName)
00487 {
00488 if (!pName)
00489 {
00490 return false;
00491 }
00492 size_t nName = strlen(pName);
00493
00494
00495
00496 if ( nName <= 0
00497 || PLAYER_NAME_LIMIT <= nName)
00498 {
00499 return false;
00500 }
00501
00502
00503
00504
00505 if ( strchr("*!#", *pName)
00506 || mux_isspace(pName[0])
00507 || mux_isspace(pName[nName-1]))
00508 {
00509 return false;
00510 }
00511
00512 if ( mudstate.bStandAlone
00513 || mudconf.name_spaces)
00514 {
00515 mux_PlayerNameSet[(unsigned char)' '] = 1;
00516 }
00517 else
00518 {
00519 mux_PlayerNameSet[(unsigned char)' '] = 0;
00520 }
00521
00522
00523
00524
00525 for (unsigned int i = 0; i < nName; i++)
00526 {
00527 if (!mux_PlayerNameSet(pName[i]))
00528 {
00529 return false;
00530 }
00531 }
00532
00533
00534
00535 if ( (nName == 2 && memcmp("me", pName, 2) == 0)
00536 || (nName == 4 && ( memcmp("home", pName, 4) == 0
00537 || memcmp("here", pName, 4) == 0)))
00538 {
00539 return false;
00540 }
00541 return true;
00542 }
00543
00544 bool ok_password(const char *password, const char **pmsg)
00545 {
00546 *pmsg = NULL;
00547
00548 if (*password == '\0')
00549 {
00550 *pmsg = "Null passwords are not allowed.";
00551 return false;
00552 }
00553
00554 const char *scan;
00555 int num_upper = 0;
00556 int num_special = 0;
00557 int num_lower = 0;
00558
00559 for (scan = password; *scan; scan++)
00560 {
00561 if ( !mux_isprint(*scan)
00562 || mux_isspace(*scan))
00563 {
00564 *pmsg = "Illegal character in password.";
00565 return false;
00566 }
00567 if (mux_isupper(*scan))
00568 {
00569 num_upper++;
00570 }
00571 else if (mux_islower(*scan))
00572 {
00573 num_lower++;
00574 }
00575 else if ( *scan != '\''
00576 && *scan != '-')
00577 {
00578 num_special++;
00579 }
00580 }
00581
00582 if ( !mudstate.bStandAlone
00583 && mudconf.safer_passwords)
00584 {
00585 if (num_upper < 1)
00586 {
00587 *pmsg = "The password must contain at least one capital letter.";
00588 return false;
00589 }
00590 if (num_lower < 1)
00591 {
00592 *pmsg = "The password must contain at least one lowercase letter.";
00593 return false;
00594 }
00595 if (num_special < 1)
00596 {
00597 *pmsg = "The password must contain at least one number or a symbol other than the apostrophe or dash.";
00598 return false;
00599 }
00600 }
00601 return true;
00602 }
00603
00604
00605
00606
00607
00608 void handle_ears(dbref thing, bool could_hear, bool can_hear)
00609 {
00610 char *buff, *bp;
00611 int gender;
00612 static const char *poss[5] =
00613 {"", "its", "her", "his", "their"};
00614
00615 if (could_hear != can_hear)
00616 {
00617 buff = alloc_lbuf("handle_ears");
00618 strcpy(buff, Name(thing));
00619 if (isExit(thing))
00620 {
00621 for (bp = buff; *bp && *bp != ';'; bp++)
00622 {
00623 ;
00624 }
00625 *bp = '\0';
00626 }
00627 gender = get_gender(thing);
00628
00629 if (can_hear)
00630 {
00631 notify_check(thing, thing,
00632 tprintf("%s grow%s ears and can now hear.",
00633 buff, (gender == 4) ? "" : "s"),
00634 (MSG_ME | MSG_NBR | MSG_LOC | MSG_INV));
00635 }
00636 else
00637 {
00638 notify_check(thing, thing,
00639 tprintf("%s lose%s %s ears and become%s deaf.",
00640 buff, (gender == 4) ? "" : "s",
00641 poss[gender], (gender == 4) ? "" : "s"),
00642 (MSG_ME | MSG_NBR | MSG_LOC | MSG_INV));
00643 }
00644 free_lbuf(buff);
00645 }
00646 }
00647
00648
00649
00650 void do_switch
00651 (
00652 dbref player,
00653 dbref caller,
00654 dbref enactor,
00655 int key,
00656 char *expr,
00657 char *args[],
00658 int nargs,
00659 char *cargs[],
00660 int ncargs
00661 )
00662 {
00663 if ( !expr
00664 || nargs <= 0)
00665 {
00666 return;
00667 }
00668
00669 if (key == SWITCH_DEFAULT)
00670 {
00671 if (mudconf.switch_df_all)
00672 {
00673 key = SWITCH_ANY;
00674 }
00675 else
00676 {
00677 key = SWITCH_ONE;
00678 }
00679 }
00680
00681
00682
00683 bool any = false;
00684 int a;
00685 char *buff, *bp, *str;
00686 buff = bp = alloc_lbuf("do_switch");
00687 CLinearTimeAbsolute lta;
00688 for ( a = 0;
00689 a < nargs - 1
00690 && args[a]
00691 && args[a + 1];
00692 a += 2)
00693 {
00694 bp = buff;
00695 str = args[a];
00696 mux_exec(buff, &bp, player, caller, enactor, EV_FCHECK | EV_EVAL | EV_TOP,
00697 &str, cargs, ncargs);
00698 *bp = '\0';
00699 if (wild_match(buff, expr))
00700 {
00701 char *tbuf = replace_tokens(args[a+1], NULL, NULL, expr);
00702 wait_que(player, caller, enactor, false, lta, NOTHING, 0,
00703 tbuf, cargs, ncargs, mudstate.global_regs);
00704 free_lbuf(tbuf);
00705 if (key == SWITCH_ONE)
00706 {
00707 free_lbuf(buff);
00708 return;
00709 }
00710 any = true;
00711 }
00712 }
00713 free_lbuf(buff);
00714 if ( a < nargs
00715 && !any
00716 && args[a])
00717 {
00718 char *tbuf = replace_tokens(args[a], NULL, NULL, expr);
00719 wait_que(player, caller, enactor, false, lta, NOTHING, 0, tbuf,
00720 cargs, ncargs, mudstate.global_regs);
00721 free_lbuf(tbuf);
00722 }
00723 }
00724
00725
00726
00727
00728 void do_if
00729 (
00730 dbref player,
00731 dbref caller,
00732 dbref enactor,
00733 int key,
00734 char *expr,
00735 char *args[],
00736 int nargs,
00737 char *cargs[],
00738 int ncargs
00739 )
00740 {
00741 UNUSED_PARAMETER(key);
00742
00743 if ( !expr
00744 || nargs <= 0)
00745 {
00746 return;
00747 }
00748
00749 char *buff, *bp;
00750 CLinearTimeAbsolute lta;
00751 buff = bp = alloc_lbuf("do_if");
00752
00753 mux_exec(buff, &bp, player, caller, enactor, EV_FCHECK | EV_EVAL | EV_TOP,
00754 &expr, cargs, ncargs);
00755 *bp = '\0';
00756
00757 int a = !xlate(buff);
00758 free_lbuf(buff);
00759
00760 if (a < nargs)
00761 {
00762 wait_que(player, caller, enactor, false, lta, NOTHING, 0, args[a],
00763 cargs, ncargs, mudstate.global_regs);
00764 }
00765 }
00766
00767 void do_addcommand
00768 (
00769 dbref player,
00770 dbref caller,
00771 dbref enactor,
00772 int key,
00773 int nargs,
00774 char *name,
00775 char *command
00776 )
00777 {
00778 UNUSED_PARAMETER(caller);
00779 UNUSED_PARAMETER(enactor);
00780 UNUSED_PARAMETER(key);
00781
00782
00783
00784 char *pName = NULL;
00785 if (1 <= nargs)
00786 {
00787 char *pStripped = strip_ansi(name);
00788 pName = RemoveSetOfCharacters(pStripped, "\r\n\t ");
00789 mux_strlwr(pName);
00790 }
00791 if ( !pName
00792 || pName[0] == '\0'
00793 || ( pName[0] == '_'
00794 && pName[1] == '_'))
00795 {
00796 notify(player, "That is not a valid command name.");
00797 return;
00798 }
00799
00800
00801
00802 dbref thing;
00803 ATTR *pattr;
00804 if ( !parse_attrib(player, command, &thing, &pattr)
00805 || !pattr)
00806 {
00807 notify(player, "No such attribute.");
00808 return;
00809 }
00810 if (!See_attr(player, thing, pattr))
00811 {
00812 notify(player, NOPERM_MESSAGE);
00813 return;
00814 }
00815
00816 CMDENT *old = (CMDENT *)hashfindLEN(pName, strlen(pName),
00817 &mudstate.command_htab);
00818
00819 CMDENT *cmd;
00820 ADDENT *add, *nextp;
00821
00822 if ( old
00823 && (old->callseq & CS_ADDED))
00824 {
00825
00826
00827 for (nextp = old->addent; nextp != NULL; nextp = nextp->next)
00828 {
00829 if ( nextp->thing == thing
00830 && nextp->atr == pattr->number)
00831 {
00832 notify(player, tprintf("%s already added.", pName));
00833 return;
00834 }
00835 }
00836
00837
00838
00839 add = (ADDENT *)MEMALLOC(sizeof(ADDENT));
00840 ISOUTOFMEMORY(add);
00841 add->thing = thing;
00842 add->atr = pattr->number;
00843 add->name = StringClone(pName);
00844 add->next = old->addent;
00845 old->addent = add;
00846 }
00847 else
00848 {
00849 if (old)
00850 {
00851
00852
00853
00854 hashdeleteLEN(pName, strlen(pName), &mudstate.command_htab);
00855 }
00856
00857 cmd = (CMDENT *)MEMALLOC(sizeof(CMDENT));
00858 ISOUTOFMEMORY(cmd);
00859 cmd->cmdname = StringClone(pName);
00860 cmd->switches = NULL;
00861 cmd->perms = 0;
00862 cmd->extra = 0;
00863 if ( old
00864 && (old->callseq & CS_LEADIN))
00865 {
00866 cmd->callseq = CS_ADDED|CS_ONE_ARG|CS_LEADIN;
00867 }
00868 else
00869 {
00870 cmd->callseq = CS_ADDED|CS_ONE_ARG;
00871 }
00872 cmd->hookmask = 0;
00873 add = (ADDENT *)MEMALLOC(sizeof(ADDENT));
00874 ISOUTOFMEMORY(add);
00875 add->thing = thing;
00876 add->atr = pattr->number;
00877 add->name = StringClone(pName);
00878 add->next = NULL;
00879 cmd->addent = add;
00880
00881 hashaddLEN(pName, strlen(pName), cmd, &mudstate.command_htab);
00882
00883 if ( old
00884 && strcmp(pName, old->cmdname) == 0)
00885 {
00886
00887
00888
00889
00890 char *p = tprintf("__%s", pName);
00891 hashdeleteLEN(p, strlen(p), &mudstate.command_htab);
00892 hashreplall(old, cmd, &mudstate.command_htab);
00893 hashaddLEN(p, strlen(p), old, &mudstate.command_htab);
00894 }
00895 }
00896
00897
00898
00899 set_prefix_cmds();
00900 notify(player, tprintf("Command %s added.", pName));
00901 }
00902
00903 void do_listcommands(dbref player, dbref caller, dbref enactor, int key,
00904 char *name)
00905 {
00906 UNUSED_PARAMETER(caller);
00907 UNUSED_PARAMETER(enactor);
00908 UNUSED_PARAMETER(key);
00909
00910 CMDENT *old;
00911 ADDENT *nextp;
00912 bool didit = false;
00913
00914
00915
00916 mux_strlwr(name);
00917
00918 if (*name)
00919 {
00920 old = (CMDENT *)hashfindLEN(name, strlen(name), &mudstate.command_htab);
00921
00922 if ( old
00923 && (old->callseq & CS_ADDED))
00924 {
00925
00926
00927
00928 for (nextp = old->addent; nextp != NULL; nextp = nextp->next)
00929 {
00930 ATTR *ap = (ATTR *)atr_num(nextp->atr);
00931 const char *pName = "(WARNING: Bad Attribute Number)";
00932 if (ap)
00933 {
00934 pName = ap->name;
00935 }
00936 notify(player, tprintf("%s: #%d/%s", nextp->name, nextp->thing, pName));
00937 }
00938 }
00939 else
00940 {
00941 notify(player, tprintf("%s not found in command table.",name));
00942 }
00943 return;
00944 }
00945 else
00946 {
00947 char *pKeyName;
00948 int nKeyName;
00949 for (old = (CMDENT *)hash_firstkey(&mudstate.command_htab, &nKeyName, &pKeyName);
00950 old != NULL;
00951 old = (CMDENT *)hash_nextkey(&mudstate.command_htab, &nKeyName, &pKeyName))
00952 {
00953 if (old->callseq & CS_ADDED)
00954 {
00955 pKeyName[nKeyName] = '\0';
00956 for (nextp = old->addent; nextp != NULL; nextp = nextp->next)
00957 {
00958 if (strcmp(pKeyName, nextp->name) != 0)
00959 {
00960 continue;
00961 }
00962 ATTR *ap = (ATTR *)atr_num(nextp->atr);
00963 const char *pName = "(WARNING: Bad Attribute Number)";
00964 if (ap)
00965 {
00966 pName = ap->name;
00967 }
00968 notify(player, tprintf("%s: #%d/%s", nextp->name,
00969 nextp->thing, pName));
00970 didit = true;
00971 }
00972 }
00973 }
00974 }
00975 if (!didit)
00976 {
00977 notify(player, "No added commands found in command table.");
00978 }
00979 }
00980
00981 void do_delcommand
00982 (
00983 dbref player,
00984 dbref caller,
00985 dbref enactor,
00986 int key,
00987 int nargs,
00988 char *name,
00989 char *command
00990 )
00991 {
00992 UNUSED_PARAMETER(caller);
00993 UNUSED_PARAMETER(enactor);
00994 UNUSED_PARAMETER(key);
00995 UNUSED_PARAMETER(nargs);
00996
00997 if (!*name)
00998 {
00999 notify(player, "Sorry.");
01000 return;
01001 }
01002
01003 dbref thing = NOTHING;
01004 int atr = NOTHING;
01005 ATTR *pattr;
01006 if (*command)
01007 {
01008 if ( !parse_attrib(player, command, &thing, &pattr)
01009 || !pattr)
01010 {
01011 notify(player, "No such attribute.");
01012 return;
01013 }
01014 if (!See_attr(player, thing, pattr))
01015 {
01016 notify(player, NOPERM_MESSAGE);
01017 return;
01018 }
01019 atr = pattr->number;
01020 }
01021
01022
01023
01024 mux_strlwr(name);
01025
01026 CMDENT *old, *cmd;
01027 ADDENT *prev = NULL, *nextp;
01028 size_t nName = strlen(name);
01029 old = (CMDENT *)hashfindLEN(name, nName, &mudstate.command_htab);
01030
01031 if ( old
01032 && (old->callseq & CS_ADDED))
01033 {
01034 char *p__Name = tprintf("__%s", name);
01035 size_t n__Name = strlen(p__Name);
01036
01037 if (command[0] == '\0')
01038 {
01039
01040
01041 for (prev = old->addent; prev != NULL; prev = nextp)
01042 {
01043 nextp = prev->next;
01044 MEMFREE(prev->name);
01045 prev->name = NULL;
01046 MEMFREE(prev);
01047 prev = NULL;
01048 }
01049 hashdeleteLEN(name, nName, &mudstate.command_htab);
01050 cmd = (CMDENT *)hashfindLEN(p__Name, n__Name, &mudstate.command_htab);
01051 if (cmd)
01052 {
01053 hashaddLEN(cmd->cmdname, strlen(cmd->cmdname), cmd,
01054 &mudstate.command_htab);
01055 if (strcmp(name, cmd->cmdname) != 0)
01056 {
01057 hashaddLEN(name, nName, cmd, &mudstate.command_htab);
01058 }
01059
01060 hashdeleteLEN(p__Name, n__Name, &mudstate.command_htab);
01061 hashaddLEN(p__Name, n__Name, cmd, &mudstate.command_htab);
01062 hashreplall(old, cmd, &mudstate.command_htab);
01063 }
01064 else
01065 {
01066
01067
01068 }
01069 MEMFREE(old->cmdname);
01070 old->cmdname = NULL;
01071 MEMFREE(old);
01072 old = NULL;
01073 set_prefix_cmds();
01074 notify(player, "Done.");
01075 }
01076 else
01077 {
01078
01079
01080 for (nextp = old->addent; nextp != NULL; nextp = nextp->next)
01081 {
01082 if ( nextp->thing == thing
01083 && nextp->atr == atr)
01084 {
01085 MEMFREE(nextp->name);
01086 nextp->name = NULL;
01087 if (!prev)
01088 {
01089 if (!nextp->next)
01090 {
01091 hashdeleteLEN(name, nName, &mudstate.command_htab);
01092 cmd = (CMDENT *)hashfindLEN(p__Name, n__Name,
01093 &mudstate.command_htab);
01094 if (cmd)
01095 {
01096 hashaddLEN(cmd->cmdname, strlen(cmd->cmdname),
01097 cmd, &mudstate.command_htab);
01098 if (strcmp(name, cmd->cmdname) != 0)
01099 {
01100 hashaddLEN(name, nName, cmd,
01101 &mudstate.command_htab);
01102 }
01103
01104 hashdeleteLEN(p__Name, n__Name,
01105 &mudstate.command_htab);
01106 hashaddLEN(p__Name, n__Name, cmd,
01107 &mudstate.command_htab);
01108 hashreplall(old, cmd,
01109 &mudstate.command_htab);
01110 }
01111 MEMFREE(old->cmdname);
01112 old->cmdname = NULL;
01113 MEMFREE(old);
01114 old = NULL;
01115 }
01116 else
01117 {
01118 old->addent = nextp->next;
01119 MEMFREE(nextp);
01120 nextp = NULL;
01121 }
01122 }
01123 else
01124 {
01125 prev->next = nextp->next;
01126 MEMFREE(nextp);
01127 nextp = NULL;
01128 }
01129 set_prefix_cmds();
01130 notify(player, "Done.");
01131 return;
01132 }
01133 prev = nextp;
01134 }
01135 notify(player, "Command not found in command table.");
01136 }
01137 }
01138 else
01139 {
01140 notify(player, "Command not found in command table.");
01141 }
01142 }
01143
01144
01145
01146
01147
01148
01149
01150
01151 void handle_prog(DESC *d, char *message)
01152 {
01153
01154
01155 if (*message == '|')
01156 {
01157 do_command(d, message + 1);
01158
01159 if (d->program_data != NULL)
01160 {
01161 queue_string(d, tprintf("%s>%s ", ANSI_HILITE, ANSI_NORMAL));
01162
01163 if (OPTION_YES == UsState(d, TELNET_EOR))
01164 {
01165
01166
01167 const char aEOR[2] = { NVT_IAC, NVT_EOR };
01168 queue_write_LEN(d, aEOR, sizeof(aEOR));
01169 }
01170 else if (OPTION_YES != UsState(d, TELNET_SGA))
01171 {
01172
01173
01174 const char aGoAhead[2] = { NVT_IAC, NVT_GA };
01175 queue_write_LEN(d, aGoAhead, sizeof(aGoAhead));
01176 }
01177 }
01178 return;
01179 }
01180 dbref aowner;
01181 int aflags, i;
01182 char *cmd = atr_get(d->player, A_PROGCMD, &aowner, &aflags);
01183 CLinearTimeAbsolute lta;
01184 wait_que(d->program_data->wait_enactor, d->player, d->player, false, lta,
01185 NOTHING, 0, cmd, (char **)&message, 1,
01186 (char **)d->program_data->wait_regs);
01187
01188
01189
01190 DESC *all = (DESC *)hashfindLEN(&(d->player), sizeof(d->player), &mudstate.desc_htab) ;
01191
01192 if (all && all->program_data)
01193 {
01194 for (i = 0; i < MAX_GLOBAL_REGS; i++)
01195 {
01196 if (all->program_data->wait_regs[i])
01197 {
01198 free_lbuf(all->program_data->wait_regs[i]);
01199 all->program_data->wait_regs[i] = NULL;
01200 }
01201 }
01202
01203 MEMFREE(all->program_data);
01204 all->program_data = NULL;
01205
01206
01207
01208 DESC_ITER_PLAYER(d->player, all)
01209 all->program_data = NULL;
01210 }
01211 atr_clr(d->player, A_PROGCMD);
01212 free_l