00001
00002
00003
00004
00005
00006 #include "copyright.h"
00007 #include "autoconf.h"
00008 #include "config.h"
00009 #include "externs.h"
00010
00011 #include "attrs.h"
00012 #include "command.h"
00013 #include "comsys.h"
00014 #include "functions.h"
00015 #include "interface.h"
00016 #include "powers.h"
00017 #include "svdreport.h"
00018 #include "sha1.h"
00019
00020 #define NUM_GOOD 4 // # of successful logins to save data for.
00021 #define NUM_BAD 3 // # of failed logins to save data for.
00022
00023 typedef struct hostdtm HOSTDTM;
00024 struct hostdtm
00025 {
00026 char *host;
00027 char *dtm;
00028 };
00029
00030 typedef struct logindata LDATA;
00031 struct logindata
00032 {
00033 HOSTDTM good[NUM_GOOD];
00034 HOSTDTM bad[NUM_BAD];
00035 int tot_good;
00036 int tot_bad;
00037 int new_bad;
00038 };
00039
00040
00041
00042
00043
00044
00045 static void decrypt_logindata(char *atrbuf, LDATA *info)
00046 {
00047 int i;
00048
00049 info->tot_good = 0;
00050 info->tot_bad = 0;
00051 info->new_bad = 0;
00052 for (i = 0; i < NUM_GOOD; i++)
00053 {
00054 info->good[i].host = NULL;
00055 info->good[i].dtm = NULL;
00056 }
00057 for (i = 0; i < NUM_BAD; i++)
00058 {
00059 info->bad[i].host = NULL;
00060 info->bad[i].dtm = NULL;
00061 }
00062
00063 if (*atrbuf == '#')
00064 {
00065 atrbuf++;
00066 info->tot_good = mux_atol(grabto(&atrbuf, ';'));
00067 for (i = 0; i < NUM_GOOD; i++)
00068 {
00069 info->good[i].host = grabto(&atrbuf, ';');
00070 info->good[i].dtm = grabto(&atrbuf, ';');
00071 }
00072 info->new_bad = mux_atol(grabto(&atrbuf, ';'));
00073 info->tot_bad = mux_atol(grabto(&atrbuf, ';'));
00074 for (i = 0; i < NUM_BAD; i++)
00075 {
00076 info->bad[i].host = grabto(&atrbuf, ';');
00077 info->bad[i].dtm = grabto(&atrbuf, ';');
00078 }
00079 }
00080 }
00081
00082 static void encrypt_logindata(char *atrbuf, LDATA *info)
00083 {
00084
00085
00086
00087 char nullc = '\0';
00088 int i;
00089 for (i = 0; i < NUM_GOOD; i++)
00090 {
00091 if (!info->good[i].host)
00092 info->good[i].host = &nullc;
00093 if (!info->good[i].dtm)
00094 info->good[i].dtm = &nullc;
00095 }
00096 for (i = 0; i < NUM_BAD; i++)
00097 {
00098 if (!info->bad[i].host)
00099 info->bad[i].host = &nullc;
00100 if (!info->bad[i].dtm)
00101 info->bad[i].dtm = &nullc;
00102 }
00103 char *bp = alloc_lbuf("encrypt_logindata");
00104 sprintf(bp, "#%d;%s;%s;%s;%s;%s;%s;%s;%s;%d;%d;%s;%s;%s;%s;%s;%s;",
00105 info->tot_good,
00106 info->good[0].host, info->good[0].dtm,
00107 info->good[1].host, info->good[1].dtm,
00108 info->good[2].host, info->good[2].dtm,
00109 info->good[3].host, info->good[3].dtm,
00110 info->new_bad, info->tot_bad,
00111 info->bad[0].host, info->bad[0].dtm,
00112 info->bad[1].host, info->bad[1].dtm,
00113 info->bad[2].host, info->bad[2].dtm);
00114 strcpy(atrbuf, bp);
00115 free_lbuf(bp);
00116 }
00117
00118
00119
00120
00121
00122
00123
00124 void record_login
00125 (
00126 dbref player,
00127 bool isgood,
00128 char *ldate,
00129 char *lhost,
00130 char *lusername,
00131 char *lipaddr
00132 )
00133 {
00134 LDATA login_info;
00135 dbref aowner;
00136 int aflags, i;
00137
00138 char *atrbuf = atr_get(player, A_LOGINDATA, &aowner, &aflags);
00139 decrypt_logindata(atrbuf, &login_info);
00140 if (isgood)
00141 {
00142 if (login_info.new_bad > 0)
00143 {
00144 notify(player, "");
00145 notify(player, tprintf("**** %d failed connect%s since your last successful connect. ****",
00146 login_info.new_bad, (login_info.new_bad == 1 ? "" : "s")));
00147 notify(player, tprintf("Most recent attempt was from %s on %s.",
00148 login_info.bad[0].host, login_info.bad[0].dtm));
00149 notify(player, "");
00150 login_info.new_bad = 0;
00151 }
00152 if ( login_info.good[0].host
00153 && *login_info.good[0].host
00154 && login_info.good[0].dtm
00155 && *login_info.good[0].dtm)
00156 {
00157 notify(player, tprintf("Last connect was from %s on %s.",
00158 login_info.good[0].host, login_info.good[0].dtm));
00159 }
00160
00161 for (i = NUM_GOOD - 1; i > 0; i--)
00162 {
00163 login_info.good[i].dtm = login_info.good[i - 1].dtm;
00164 login_info.good[i].host = login_info.good[i - 1].host;
00165 }
00166 login_info.good[0].dtm = ldate;
00167 login_info.good[0].host = lhost;
00168 login_info.tot_good++;
00169 if (*lusername)
00170 {
00171 atr_add_raw(player, A_LASTSITE, tprintf("%s@%s", lusername, lhost));
00172 }
00173 else
00174 {
00175 atr_add_raw(player, A_LASTSITE, lhost);
00176 }
00177
00178
00179
00180 atr_add_raw(player, A_LASTIP, lipaddr);
00181 }
00182 else
00183 {
00184 for (i = NUM_BAD - 1; i > 0; i--)
00185 {
00186 login_info.bad[i].dtm = login_info.bad[i - 1].dtm;
00187 login_info.bad[i].host = login_info.bad[i - 1].host;
00188 }
00189 login_info.bad[0].dtm = ldate;
00190 login_info.bad[0].host = lhost;
00191 login_info.tot_bad++;
00192 login_info.new_bad++;
00193 }
00194 encrypt_logindata(atrbuf, &login_info);
00195 atr_add_raw(player, A_LOGINDATA, atrbuf);
00196 free_lbuf(atrbuf);
00197 }
00198
00199 const char Base64Table[65] =
00200 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00201
00202 #define ENCODED_LENGTH(x) ((((x)+2)/3)*4)
00203
00204 static void EncodeBase64(size_t nIn, const char *pIn, char *pOut)
00205 {
00206 size_t nTriples = nIn/3;
00207 size_t nLeftover = nIn%3;
00208 UINT32 stage;
00209
00210 const UINT8 *p = (const UINT8 *)pIn;
00211 UINT8 *q = ( UINT8 *)pOut;
00212
00213 while (nTriples--)
00214 {
00215 stage = (p[0] << 16) | (p[1] << 8) | p[2];
00216
00217 q[0] = Base64Table[(stage >> 18) ];
00218 q[1] = Base64Table[(stage >> 12) & 0x3F];
00219 q[2] = Base64Table[(stage >> 6) & 0x3F];
00220 q[3] = Base64Table[(stage ) & 0x3F];
00221
00222 q += 4;
00223 p += 3;
00224 }
00225
00226 switch (nLeftover)
00227 {
00228 case 1:
00229 stage = p[0] << 16;
00230
00231 q[0] = Base64Table[(stage >> 18) ];
00232 q[1] = Base64Table[(stage >> 12) & 0x3F];
00233 q[2] = '=';
00234 q[3] = '=';
00235
00236 q += 4;
00237 break;
00238
00239 case 2:
00240 stage = (p[0] << 16) | (p[1] << 8);
00241
00242 q[0] = Base64Table[(stage >> 18) ];
00243 q[1] = Base64Table[(stage >> 12) & 0x3F];
00244 q[2] = Base64Table[(stage >> 6) & 0x3F];
00245 q[3] = '=';
00246
00247 q += 4;
00248 break;
00249 }
00250 q[0] = '\0';
00251 }
00252
00253 #define SHA1_PREFIX_LENGTH 6
00254 const char szSHA1Prefix[SHA1_PREFIX_LENGTH+1] = "$SHA1$";
00255 #define ENCODED_HASH_LENGTH ENCODED_LENGTH(5*sizeof(UINT32))
00256
00257 #define MD5_PREFIX_LENGTH 3
00258 const char szMD5Prefix[MD5_PREFIX_LENGTH+1] = "$1$";
00259
00260 #define BLOWFISH_PREFIX_LENGTH 4
00261 const char szBlowfishPrefix[BLOWFISH_PREFIX_LENGTH+1] = "$2a$";
00262
00263 #define SALT_LENGTH 9
00264 #define ENCODED_SALT_LENGTH ENCODED_LENGTH(SALT_LENGTH)
00265
00266 static const char *GenerateSalt(void)
00267 {
00268 char szSaltRaw[SALT_LENGTH+1];
00269 int i;
00270 for (i = 0; i < SALT_LENGTH; i++)
00271 {
00272 szSaltRaw[i] = (char)RandomINT32(0, 255);
00273 }
00274 szSaltRaw[SALT_LENGTH] = '\0';
00275
00276 static char szSaltEncoded[SHA1_PREFIX_LENGTH + ENCODED_SALT_LENGTH+1];
00277 strcpy(szSaltEncoded, szSHA1Prefix);
00278 EncodeBase64(SALT_LENGTH, szSaltRaw, szSaltEncoded + SHA1_PREFIX_LENGTH);
00279 return szSaltEncoded;
00280 }
00281
00282 void ChangePassword(dbref player, const char *szPassword)
00283 {
00284 int iType;
00285 s_Pass(player, mux_crypt(szPassword, GenerateSalt(), &iType));
00286 }
00287
00288 #define CRYPT_FAIL 0
00289 #define CRYPT_SHA1 1
00290 #define CRYPT_MD5 2
00291 #define CRYPT_DES 3
00292 #define CRYPT_DES_EXT 4
00293 #define CRYPT_BLOWFISH 5
00294 #define CRYPT_CLEARTEXT 6
00295 #define CRYPT_OTHER 7
00296
00297 const char szFail[] = "$FAIL$$";
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 const char *mux_crypt(const char *szPassword, const char *szSetting, int *piType)
00308 {
00309 const char *pSaltField = NULL;
00310 size_t nSaltField = 0;
00311
00312 *piType = CRYPT_FAIL;
00313
00314 if (szSetting[0] == '$')
00315 {
00316 const char *p = strchr(szSetting+1, '$');
00317 if (p)
00318 {
00319 p++;
00320 size_t nAlgo = p - szSetting;
00321 if ( nAlgo == SHA1_PREFIX_LENGTH
00322 && memcmp(szSetting, szSHA1Prefix, SHA1_PREFIX_LENGTH) == 0)
00323 {
00324
00325
00326 pSaltField = p;
00327 p = strchr(pSaltField, '$');
00328 if (p)
00329 {
00330 nSaltField = p - pSaltField;
00331 }
00332 else
00333 {
00334 nSaltField = strlen(pSaltField);
00335 }
00336 if (nSaltField <= ENCODED_SALT_LENGTH)
00337 {
00338 *piType = CRYPT_SHA1;
00339 }
00340 }
00341 else if ( nAlgo == MD5_PREFIX_LENGTH
00342 && memcmp(szSetting, szMD5Prefix, MD5_PREFIX_LENGTH) == 0)
00343 {
00344 *piType = CRYPT_MD5;
00345 }
00346 else if ( nAlgo == BLOWFISH_PREFIX_LENGTH
00347 && memcmp(szSetting, szBlowfishPrefix, BLOWFISH_PREFIX_LENGTH) == 0)
00348 {
00349 *piType = CRYPT_BLOWFISH;
00350 }
00351 else
00352 {
00353 *piType = CRYPT_OTHER;
00354 }
00355 }
00356 }
00357 else if (szSetting[0] == '_')
00358 {
00359 *piType = CRYPT_DES_EXT;
00360 }
00361 else
00362 {
00363 #if 0
00364
00365
00366 *piType = CRYPT_DES;
00367 #else
00368
00369
00370
00371
00372
00373
00374 size_t nSetting = strlen(szSetting);
00375 if ( nSetting == 13
00376 && memcmp(szSetting, "XX", 2) == 0)
00377 {
00378 *piType = CRYPT_DES;
00379 }
00380 else
00381 {
00382 *piType = CRYPT_CLEARTEXT;
00383 }
00384 #endif
00385 }
00386
00387 switch (*piType)
00388 {
00389 case CRYPT_FAIL:
00390 return szFail;
00391
00392 case CRYPT_CLEARTEXT:
00393 return szPassword;
00394
00395 case CRYPT_MD5:
00396 case CRYPT_BLOWFISH:
00397 case CRYPT_OTHER:
00398 case CRYPT_DES_EXT:
00399 #ifdef WIN32
00400
00401
00402 return szFail;
00403 #endif // WIN32
00404
00405 case CRYPT_DES:
00406 #if defined(HAVE_LIBCRYPT) \
00407 || defined(HAVE_CRYPT)
00408 return crypt(szPassword, szSetting);
00409 #else
00410 return szFail;
00411 #endif
00412 }
00413
00414
00415
00416 SHA1_CONTEXT shac;
00417
00418 SHA1_Init(&shac);
00419 SHA1_Compute(&shac, nSaltField, pSaltField);
00420 SHA1_Compute(&shac, strlen(szPassword), szPassword);
00421 SHA1_Final(&shac);
00422
00423
00424
00425 char szHashRaw[21];
00426 char *p = szHashRaw;
00427
00428 int i;
00429 for (i = 0; i <= 4; i++)
00430 {
00431 *p++ = (UINT8)(shac.H[i] >> 24);
00432 *p++ = (UINT8)(shac.H[i] >> 16);
00433 *p++ = (UINT8)(shac.H[i] >> 8);
00434 *p++ = (UINT8)(shac.H[i] );
00435 }
00436 *p = '\0';
00437
00438
00439
00440
00441
00442 static char buf[SHA1_PREFIX_LENGTH + ENCODED_SALT_LENGTH + 1 + ENCODED_HASH_LENGTH + 1 + 16];
00443 strcpy(buf, szSHA1Prefix);
00444 memcpy(buf + SHA1_PREFIX_LENGTH, pSaltField, nSaltField);
00445 buf[SHA1_PREFIX_LENGTH + nSaltField] = '$';
00446 EncodeBase64(20, szHashRaw, buf + SHA1_PREFIX_LENGTH + nSaltField + 1);
00447 return buf;
00448 }
00449
00450
00451
00452
00453
00454 static bool check_pass(dbref player, const char *pPassword)
00455 {
00456 bool bValidPass = false;
00457 int iType;
00458
00459 int aflags;
00460 dbref aowner;
00461 char *pTarget = atr_get(player, A_PASS, &aowner, &aflags);
00462 if (*pTarget)
00463 {
00464 if (strcmp(mux_crypt(pPassword, pTarget, &iType), pTarget) == 0)
00465 {
00466 bValidPass = true;
00467 if (iType != CRYPT_SHA1)
00468 {
00469 ChangePassword(player, pPassword);
00470 }
00471 }
00472 }
00473 #if 0
00474 else if (GOD == player)
00475 {
00476
00477
00478 bValidPass = true;
00479 ChangePassword(player, pPassword);
00480 }
00481 #endif
00482 free_lbuf(pTarget);
00483 return bValidPass;
00484 }
00485
00486
00487
00488
00489
00490 dbref connect_player(char *name, char *password, char *host, char *username, char *ipaddr)
00491 {
00492 CLinearTimeAbsolute ltaNow;
00493 ltaNow.GetLocal();
00494 char *time_str = ltaNow.ReturnDateString(7);
00495
00496 dbref player = lookup_player(NOTHING, name, false);
00497 if (player == NOTHING)
00498 {
00499 return NOTHING;
00500 }
00501 if (!check_pass(player, password))
00502 {
00503 record_login(player, false, time_str, host, username, ipaddr);
00504 return NOTHING;
00505 }
00506
00507
00508
00509 int aflags;
00510 dbref aowner;
00511 char *player_last = atr_get(player, A_LAST, &aowner, &aflags);
00512 if (strncmp(player_last, time_str, 10) != 0)
00513 {
00514 char *allowance = atr_pget(player, A_ALLOWANCE, &aowner, &aflags);
00515 if (*allowance == '\0')
00516 {
00517 giveto(player, mudconf.paycheck);
00518 }
00519 else
00520 {
00521 giveto(player, mux_atol(allowance));
00522 }
00523 free_lbuf(allowance);
00524 }
00525 free_lbuf(player_last);
00526 atr_add_raw(player, A_LAST, time_str);
00527 return player;
00528 }
00529
00530 void AddToPublicChannel(dbref player)
00531 {
00532 if ( mudconf.public_channel[0] != '\0'
00533 && mudconf.public_channel_alias[0] != '\0')
00534 {
00535 do_addcom(player, player, player, 0, 2,
00536 mudconf.public_channel_alias, mudconf.public_channel);
00537 }
00538 }
00539
00540
00541
00542
00543
00544 dbref create_player
00545 (
00546 char *name,
00547 char *password,
00548 dbref creator,
00549 bool isrobot,
00550 const char **pmsg
00551 )
00552 {
00553 *pmsg = NULL;
00554
00555
00556
00557 if (ThrottlePlayerCreate())
00558 {
00559 *pmsg = "The limit of new players for this hour has been reached. Please try again later.";
00560 return NOTHING;
00561 }
00562
00563
00564
00565 char *pbuf = trim_spaces(password);
00566 if (!ok_password(pbuf, pmsg))
00567 {
00568 free_lbuf(pbuf);
00569 return NOTHING;
00570 }
00571
00572
00573
00574 dbref player = create_obj(creator, TYPE_PLAYER, name, isrobot);
00575 if (player == NOTHING)
00576 {
00577 *pmsg = "Either there is already a player with that name, or that name is illegal.";
00578 free_lbuf(pbuf);
00579 return NOTHING;
00580 }
00581
00582
00583
00584 ChangePassword(player, pbuf);
00585 s_Home(player, start_home());
00586 free_lbuf(pbuf);
00587 local_data_create(player);
00588 return player;
00589 }
00590
00591
00592
00593
00594
00595 void do_password
00596 (
00597 dbref executor,
00598 dbref caller,
00599 dbref enactor,
00600 int key,
00601 int nargs,
00602 char *oldpass,
00603 char *newpass
00604 )
00605 {
00606 UNUSED_PARAMETER(caller);
00607 UNUSED_PARAMETER(enactor);
00608 UNUSED_PARAMETER(key);
00609 UNUSED_PARAMETER(nargs);
00610
00611 dbref aowner;
00612 int aflags;
00613 char *target = atr_get(executor, A_PASS, &aowner, &aflags);
00614 const char *pmsg;
00615 if ( !*target
00616 || !check_pass(executor, oldpass))
00617 {
00618 notify(executor, "Sorry.");
00619 }
00620 else if (ok_password(newpass, &pmsg))
00621 {
00622 ChangePassword(executor, newpass);
00623 notify(executor, "Password changed.");
00624 }
00625 else
00626 {
00627 notify(executor, pmsg);
00628 }
00629 free_lbuf(target);
00630 }
00631
00632
00633
00634
00635
00636 static void disp_from_on(dbref player, char *dtm_str, char *host_str)
00637 {
00638 if (dtm_str && *dtm_str && host_str && *host_str)
00639 {
00640 notify(player,
00641 tprintf(" From: %s On: %s", dtm_str, host_str));
00642 }
00643 }
00644
00645 void do_last(dbref executor, dbref caller, dbref enactor, int key, char *who)
00646 {
00647 UNUSED_PARAMETER(caller);
00648 UNUSED_PARAMETER(enactor);
00649 UNUSED_PARAMETER(key);
00650
00651 dbref target, aowner;
00652 int i, aflags;
00653
00654 if ( !who
00655 || !*who)
00656 {
00657 target = Owner(executor);
00658 }
00659 else if (string_compare(who, "me") == 0)
00660 {
00661 target = Owner(executor);
00662 }
00663 else
00664 {
00665 target = lookup_player(executor, who, true);
00666 }
00667
00668 if (target == NOTHING)
00669 {
00670 notify(executor, "I couldn't find that player.");
00671 }
00672 else if (!Controls(executor, target))
00673 {
00674 notify(executor, NOPERM_MESSAGE);
00675 }
00676 else
00677 {
00678 char *atrbuf = atr_get(target, A_LOGINDATA, &aowner, &aflags);
00679 LDATA login_info;
00680 decrypt_logindata(atrbuf, &login_info);
00681
00682 notify(executor, tprintf("Total successful connects: %d", login_info.tot_good));
00683 for (i = 0; i < NUM_GOOD; i++)
00684 {
00685 disp_from_on(executor, login_info.good[i].host, login_info.good[i].dtm);
00686 }
00687 notify(executor, tprintf("Total failed connects: %d", login_info.tot_bad));
00688 for (i = 0; i < NUM_BAD; i++)
00689 {
00690 disp_from_on(executor, login_info.bad[i].host, login_info.bad[i].dtm);
00691 }
00692 free_lbuf(atrbuf);
00693 }
00694 }
00695
00696
00697
00698
00699
00700
00701 bool add_player_name(dbref player, const char *name)
00702 {
00703 bool stat;
00704 char *temp, *tp;
00705
00706
00707
00708 tp = temp = alloc_lbuf("add_player_name");
00709 safe_str(name, temp, &tp);
00710 *tp = '\0';
00711 mux_strlwr(temp);
00712
00713 dbref *p = (int *)hashfindLEN(temp, strlen(temp), &mudstate.player_htab);
00714 if (p)
00715 {
00716
00717
00718
00719
00720 if (Good_obj(*p) && isPlayer(*p))
00721 {
00722 free_lbuf(temp);
00723 if (*p == player)
00724 {
00725 return true;
00726 }
00727 else
00728 {
00729 return false;
00730 }
00731 }
00732
00733
00734
00735 MEMFREE(p);
00736 p = (dbref *)MEMALLOC(sizeof(int));
00737 ISOUTOFMEMORY(p);
00738
00739 *p = player;
00740 stat = hashreplLEN(temp, strlen(temp), p, &mudstate.player_htab);
00741 free_lbuf(temp);
00742 }
00743 else
00744 {
00745 p = (dbref *)MEMALLOC(sizeof(int));
00746 ISOUTOFMEMORY(p);
00747
00748 *p = player;
00749 stat = (hashaddLEN(temp, strlen(temp), p, &mudstate.player_htab) >= 0);
00750 free_lbuf(temp);
00751 }
00752 return stat;
00753 }
00754
00755 bool delete_player_name(dbref player, const char *name)
00756 {
00757 char *temp, *tp;
00758
00759 tp = temp = alloc_lbuf("delete_player_name");
00760 safe_str(name, temp, &tp);
00761 *tp = '\0';
00762 mux_strlwr(temp);
00763
00764 dbref *p = (int *)hashfindLEN(temp, strlen(temp), &mudstate.player_htab);
00765 if ( !p
00766 || *p == NOTHING
00767 || ( player != NOTHING
00768 && *p != player))
00769 {
00770 free_lbuf(temp);
00771 return false;
00772 }
00773 MEMFREE(p);
00774 p = NULL;
00775 hashdeleteLEN(temp, strlen(temp), &mudstate.player_htab);
00776 free_lbuf(temp);
00777 return true;
00778 }
00779
00780 dbref lookup_player(dbref doer, char *name, bool check_who)
00781 {
00782 if (string_compare(name, "me") == 0)
00783 {
00784 return doer;
00785 }
00786
00787 while (*name == LOOKUP_TOKEN)
00788 {
00789 name++;
00790 }
00791 dbref thing;
00792 if (*name == NUMBER_TOKEN)
00793 {
00794 name++;
00795 if (!is_integer(name, NULL))
00796 {
00797 return NOTHING;
00798 }
00799 thing = mux_atol(name);
00800 if (!Good_obj(thing))
00801 {
00802 return NOTHING;
00803 }
00804 if ( !( isPlayer(thing)
00805 || God(doer)))
00806 {
00807 thing = NOTHING;
00808 }
00809 return thing;
00810 }
00811 char *temp, *tp;
00812 tp = temp = alloc_lbuf("lookup_player");
00813 safe_str(name, temp, &tp);
00814 *tp = '\0';
00815 mux_strlwr(temp);
00816 dbref *p = (int *)hashfindLEN(temp, strlen(temp), &mudstate.player_htab);
00817 free_lbuf(temp);
00818 if (!p)
00819 {
00820 if (check_who)
00821 {
00822 thing = find_connected_name(doer, name);
00823 if (Hidden(thing))
00824 {
00825 thing = NOTHING;
00826 }
00827 }
00828 else
00829 {
00830 thing = NOTHING;
00831 }
00832 }
00833 else if (!Good_obj(*p))
00834 {
00835 thing = NOTHING;
00836 }
00837 else
00838 {
00839 thing = *p;
00840 }
00841
00842 return thing;
00843 }
00844
00845 void load_player_names(void)
00846 {
00847 dbref i;
00848 DO_WHOLE_DB(i)
00849 {
00850 if (isPlayer(i))
00851 {
00852 add_player_name(i, Name(i));
00853 }
00854 }
00855 char *alias = alloc_lbuf("load_player_names");
00856 DO_WHOLE_DB(i)
00857 {
00858 if (isPlayer(i))
00859 {
00860 dbref aowner;
00861 int aflags;
00862 alias = atr_pget_str(alias, i, A_ALIAS, &aowner, &aflags);
00863 if (*alias)
00864 {
00865 add_player_name(i, alias);
00866 }
00867 }
00868 }
00869 free_lbuf(alias);
00870 }
00871
00872
00873
00874
00875
00876 void badname_add(char *bad_name)
00877 {
00878
00879
00880 BADNAME *bp = (BADNAME *)MEMALLOC(sizeof(BADNAME));
00881 ISOUTOFMEMORY(bp);
00882 bp->name = StringClone(bad_name);
00883 bp->next = mudstate.badname_head;
00884 mudstate.badname_head = bp;
00885 }
00886
00887 void badname_remove(char *bad_name)
00888 {
00889
00890
00891 BADNAME *bp;
00892 BADNAME *backp = NULL;
00893 for (bp = mudstate.badname_head; bp; backp = bp, bp = bp->next)
00894 {
00895 if (!string_compare(bad_name, bp->name))
00896 {
00897 if (backp)
00898 {
00899 backp->next = bp->next;
00900 }
00901 else
00902 {
00903 mudstate.badname_head = bp->next;
00904 }
00905 MEMFREE(bp->name);
00906 bp->name = NULL;
00907 MEMFREE(bp);
00908 bp = NULL;
00909 return;
00910 }
00911 }
00912 }
00913
00914 bool badname_check(char *bad_name)
00915 {
00916 BADNAME *bp;
00917
00918
00919
00920
00921 for (bp = mudstate.badname_head; bp; bp = bp->next)
00922 {
00923 mudstate.wild_invk_ctr = 0;
00924 if (quick_wild(bp->name, bad_name))
00925 {
00926 return false;
00927 }
00928 }
00929 return true;
00930 }
00931
00932 void badname_list(dbref player, const char *prefix)
00933 {
00934 BADNAME *bp;
00935 char *buff, *bufp;
00936
00937
00938
00939 buff = bufp = alloc_lbuf("badname_list");
00940 safe_str(prefix, buff, &bufp);
00941 for (bp = mudstate.badname_head; bp; bp = bp->next)
00942 {
00943 safe_chr(' ', buff, &bufp);
00944 safe_str(bp->name, buff, &bufp);
00945 }
00946 *bufp = '\0';
00947
00948
00949
00950 notify(player, buff);
00951 free_lbuf(buff);
00952 }