00001
00002
00003
00004
00005
00006
00007
00008 #include "copyright.h"
00009 #include "autoconf.h"
00010 #include "config.h"
00011 #include "externs.h"
00012
00013 #include <stdlib.h>
00014
00015 #include "attrs.h"
00016 #include "mguests.h"
00017 #include "powers.h"
00018 #include "comsys.h"
00019
00020 #define GUEST_HYSTERESIS 20
00021
00022 CGuests Guest;
00023
00024 CGuests::CGuests(void)
00025 {
00026 Guests = NULL;
00027 nGuests = 0;
00028 nMaxGuests = 0;
00029 }
00030
00031 CGuests::~CGuests(void)
00032 {
00033 if (Guests)
00034 {
00035 MEMFREE(Guests);
00036 Guests = NULL;
00037 nGuests = 0;
00038 nMaxGuests = 0;
00039 }
00040 }
00041
00042 void CGuests::StartUp(void)
00043 {
00044 if ( !Good_obj(mudconf.guest_char)
00045 || mudconf.number_guests <= 0)
00046 {
00047
00048
00049 return;
00050 }
00051
00052
00053
00054
00055
00056
00057 dbref thing;
00058 DO_WHOLE_DB(thing)
00059 {
00060 if ( Guest(thing)
00061 && isPlayer(thing))
00062 {
00063 SizeGuests(nGuests+1);
00064 Guests[nGuests] = thing;
00065 nGuests++;
00066 }
00067 }
00068
00069
00070
00071 for (; nGuests < mudconf.min_guests; nGuests++)
00072 {
00073 SizeGuests(nGuests+1);
00074 Guests[nGuests] = MakeGuestChar();
00075
00076
00077
00078
00079 if (Guests[nGuests] == NOTHING)
00080 {
00081 break;
00082 }
00083 }
00084 }
00085
00086 void CGuests::SizeGuests(int nMin)
00087 {
00088
00089
00090
00091 if (nMin < nGuests)
00092 {
00093 nMin = nGuests;
00094 }
00095 if ( nMaxGuests <= nMin + GUEST_HYSTERESIS
00096 && nMin <= nMaxGuests)
00097 {
00098 return;
00099 }
00100
00101 dbref *newGuests = (dbref *)MEMALLOC(nMin * sizeof(dbref));
00102 if (Guests)
00103 {
00104 memcpy(newGuests, Guests, nGuests * sizeof(dbref));
00105 MEMFREE(Guests);
00106 Guests = NULL;
00107 }
00108 Guests = newGuests;
00109 nMaxGuests = nMin;
00110 }
00111
00112 const char *CGuests::Create(DESC *d)
00113 {
00114
00115
00116 if (!Good_obj(mudconf.guest_char))
00117 {
00118 return NULL;
00119 }
00120
00121
00122
00123 int i;
00124 for (i = 0; i < nGuests; i++)
00125 {
00126 dbref guest_player = Guests[i];
00127
00128
00129
00130
00131 if ( !Good_obj(guest_player)
00132 || !isPlayer(guest_player)
00133 || !Guest(guest_player))
00134 {
00135 guest_player = Guests[i] = MakeGuestChar();
00136 if (guest_player == NOTHING)
00137 {
00138 return NULL;
00139 }
00140 else
00141 {
00142 return Name(guest_player);
00143 }
00144 }
00145
00146 if (!Connected(guest_player))
00147 {
00148
00149
00150 sprintf(name, "%s%d", mudconf.guest_prefix, i+1);
00151 dbref j = lookup_player(GOD, name, false);
00152 if (j == NOTHING)
00153 {
00154 delete_player_name(guest_player, Name(guest_player));
00155 s_Name(guest_player, name);
00156 add_player_name(guest_player, Name(guest_player));
00157 }
00158 else
00159 {
00160
00161
00162 ReleaseAllResources(guest_player);
00163 AddToGuestChannel(guest_player);
00164 }
00165
00166
00167
00168 db[guest_player].fs = mudconf.player_flags;
00169
00170
00171
00172 db[guest_player].fs.word[FLAG_WORD1] |= TYPE_PLAYER;
00173 db[guest_player].fs.word[FLAG_WORD1] &= ~WIZARD;
00174
00175
00176
00177 s_Guest(guest_player);
00178
00179 move_object(guest_player, mudconf.start_room);
00180 s_Pennies(guest_player, Pennies(mudconf.guest_char));
00181 s_Zone(guest_player, Zone(mudconf.guest_char));
00182 s_Parent(guest_player, Parent(mudconf.guest_char));
00183
00184
00185
00186 WipeAttrs(guest_player);
00187 ChangePassword(guest_player, GUEST_PASSWORD);
00188
00189
00190
00191 atr_cpy(guest_player, mudconf.guest_char, true);
00192 return Name(guest_player);
00193 }
00194 }
00195
00196 if (nGuests >= mudconf.number_guests)
00197 {
00198 queue_string(d, "Sorry, All guests are currently busy. Try again later.\n");
00199 return NULL;
00200 }
00201 dbref newGuest = MakeGuestChar();
00202 if (newGuest == NOTHING)
00203 {
00204 queue_string(d, "GAME: Error creating guest, please try again later.\n");
00205 return NULL;
00206 }
00207 SizeGuests(nGuests+1);
00208 Guests[nGuests] = newGuest;
00209 nGuests++;
00210 return Name(newGuest);
00211 }
00212
00213 void CGuests::CleanUp(void)
00214 {
00215
00216
00217
00218 int nPool = nGuests;
00219 if (mudconf.min_guests < nGuests)
00220 {
00221 nPool = mudconf.min_guests;
00222 }
00223 int i;
00224 for (i = 0; i < nPool; i++)
00225 {
00226 if ( !Good_obj(Guests[i])
00227 || !isPlayer(Guests[i])
00228 || !Guest(Guests[i]))
00229 {
00230 Guests[i] = MakeGuestChar();
00231 }
00232 }
00233
00234 if (nGuests <= mudconf.min_guests)
00235 {
00236 return;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245 int itmp;
00246 int currGuest = mudconf.min_guests;
00247 for (i = mudconf.min_guests; i < nGuests; i++)
00248 {
00249 if (Connected(Guests[i]))
00250 {
00251 if (i > currGuest)
00252 {
00253 itmp = Guests[currGuest];
00254 Guests[currGuest] = Guests[i];
00255 Guests[i] = itmp;
00256 }
00257 currGuest++;
00258 }
00259 }
00260
00261
00262
00263 itmp = nGuests;
00264 for (i = mudconf.min_guests; i < itmp;i++)
00265 {
00266 if (!Connected(Guests[i]))
00267 {
00268 if (Good_obj(Guests[i]))
00269 {
00270 DestroyGuestChar(Guests[i]);
00271 }
00272 nGuests--;
00273 }
00274 }
00275 SizeGuests(nGuests);
00276 }
00277
00278 dbref CGuests::MakeGuestChar(void)
00279 {
00280
00281
00282 int i;
00283 dbref player;
00284 bool bFound = false;
00285 for (i = 0; i < mudconf.number_guests;i++)
00286 {
00287 sprintf(name, "%s%d", mudconf.guest_prefix, i + 1);
00288 player = lookup_player(GOD, name, false);
00289 if (player == NOTHING)
00290 {
00291 bFound = true;
00292 break;
00293 }
00294 }
00295 if (!bFound)
00296 {
00297 return NOTHING;
00298 }
00299
00300
00301
00302 const char *pmsg;
00303 player = create_player(name, GUEST_PASSWORD, mudconf.guest_nuker, false, &pmsg);
00304
00305
00306
00307 if (player == NOTHING)
00308 {
00309 log_text("GUEST: failed in create_player" ENDLINE);
00310 return NOTHING;
00311 }
00312
00313
00314
00315
00316 AddToGuestChannel(player);
00317 s_Guest(player);
00318 move_object(player, mudconf.start_room);
00319 db[player].fs.word[FLAG_WORD1] &= ~WIZARD;
00320 s_Pennies(player, Pennies(mudconf.guest_char));
00321 s_Zone(player, Zone(mudconf.guest_char));
00322 s_Parent(player, Parent(mudconf.guest_char));
00323
00324
00325
00326 atr_cpy(player, mudconf.guest_char, true);
00327
00328
00329
00330 do_lock(player, player, player, A_LOCK, 2, tprintf("#%d", player), "=me");
00331 do_lock(player, player, player, A_LENTER, 2, tprintf("#%d", player), "=me");
00332
00333
00334
00335 return player;
00336 }
00337
00338 void CGuests::DestroyGuestChar(dbref guest)
00339 {
00340
00341
00342 if (!Guest(guest))
00343 {
00344 return;
00345 }
00346
00347
00348
00349 if ( !Wizard(mudconf.guest_nuker)
00350 || !Good_obj(mudconf.guest_nuker))
00351 {
00352 mudconf.guest_nuker = GOD;
00353 }
00354
00355
00356
00357 destroy_player(mudconf.guest_nuker, guest);
00358 }
00359
00360 void CGuests::WipeAttrs(dbref guest)
00361 {
00362 olist_push();
00363
00364 int atr;
00365 char *as;
00366 for (atr = atr_head(guest, &as); atr; atr = atr_next(&as))
00367 {
00368 ATTR *ap = atr_num(atr);
00369 if (ap)
00370 {
00371
00372
00373 if (bCanSetAttr(GOD, guest, ap))
00374 {
00375 atr_clr(guest, ap->number);
00376 }
00377 }
00378 }
00379 olist_pop();
00380 }
00381
00382 bool CGuests::CheckGuest(dbref player)
00383 {
00384 int i;
00385 for (i = 0; i < nGuests; i++)
00386 {
00387 if (Guests[i] == player)
00388 {
00389 return true;
00390 }
00391 }
00392 return false;
00393 }
00394
00395
00396
00397 void CGuests::ListAll(dbref player)
00398 {
00399 notify(player, "--------------------------- Current Guests Listing ---------------------------");
00400 notify(player, "*Guest # : Name dbref Status Last Site");
00401 notify(player, "------------------------------------------------------------------------------");\
00402 char *buff = alloc_lbuf("CGuests-ListAll");
00403 int i;
00404 char *LastSite=alloc_lbuf("CGuests-LastSite");
00405 for (i = 0; i < nGuests; i++)
00406 {
00407 dbref aowner;
00408 int aflags;
00409 atr_get_str(LastSite, Guests[i], A_LASTSITE, &aowner, &aflags);
00410 sprintf(buff, "%sGuest %-3d: %-15s #%-5d %-10s %s",
00411 (i<mudconf.min_guests ? "*" : " "),
00412 i, Name(Guests[i]), Guests[i],
00413 (Connected(Guests[i]) ? "Online" : "NotOnline"),
00414 LastSite);
00415 notify(player, buff);
00416 if (!Good_obj(Guests[i]))
00417 {
00418 notify(player, tprintf("*** Guest %d (#%d) is an invalid object!",
00419 i, Guests[i]));
00420 }
00421 }
00422 free_lbuf(LastSite);
00423 notify(player, tprintf("----------------------------- Total Guests: %-3d -----------------------------", nGuests));
00424 free_lbuf(buff);
00425 }
00426
00427 void CGuests::AddToGuestChannel(dbref player)
00428 {
00429 if ( mudconf.guests_channel[0] != '\0'
00430 && mudconf.guests_channel_alias[0] != '\0')
00431 {
00432 do_addcom(player, player, player, 0, 2,
00433 mudconf.guests_channel_alias, mudconf.guests_channel);
00434 }
00435 }
00436
00437 char CGuests::name[50];