mux/src/walkdb.cpp

Go to the documentation of this file.
00001 // walkdb.cpp -- Support for commands that walk the entire db.
00002 //
00003 // $Id: walkdb.cpp,v 1.13 2006/05/18 17:57:48 sdennis Exp $
00004 //
00005 
00006 #include "copyright.h"
00007 #include "autoconf.h"
00008 #include "config.h"
00009 #include "externs.h"
00010 
00011 #include "misc.h"
00012 #include "attrs.h"
00013 #include "command.h"
00014 
00015 // Bind occurances of the universal var in ACTION to ARG, then run ACTION.
00016 // Cmds run in low-prio Q after a 1 sec delay for the first one.
00017 //
00018 static void bind_and_queue(dbref executor, dbref caller, dbref enactor,
00019                            char *action, char *argstr, char *cargs[],
00020                            int ncargs, int number)
00021 {
00022     char *command = replace_tokens(action, argstr, mux_ltoa_t(number), NULL);
00023     CLinearTimeAbsolute lta;
00024     wait_que(executor, caller, enactor, false, lta, NOTHING, 0, command,
00025         cargs, ncargs, mudstate.global_regs);
00026     free_lbuf(command);
00027 }
00028 
00029 // New @dolist.  i.e.:
00030 // @dolist #12 #34 #45 #123 #34644=@emit [name(##)]
00031 //
00032 // New switches added 12/92, /space (default) delimits list using spaces,
00033 // and /delimit allows specification of a delimiter.
00034 //
00035 void do_dolist(dbref executor, dbref caller, dbref enactor, int key,
00036                char *list, char *command, char *cargs[], int ncargs)
00037 {
00038     if (!list || *list == '\0')
00039     {
00040         notify(executor, "That's terrific, but what should I do with the list?");
00041         return;
00042     }
00043     char *objstring, delimiter = ' ';
00044     int number = 0;
00045     char *curr = list;
00046 
00047     if (key & DOLIST_DELIMIT)
00048     {
00049         char *tempstr = parse_to(&curr, ' ', EV_STRIP_CURLY);
00050         if (strlen(tempstr) > 1)
00051         {
00052             notify(executor, "The delimiter must be a single character!");
00053             return;
00054         }
00055         delimiter = *tempstr;
00056     }
00057     while (curr && *curr)
00058     {
00059         while (*curr == delimiter)
00060         {
00061             curr++;
00062         }
00063         if (*curr)
00064         {
00065             number++;
00066             objstring = parse_to(&curr, delimiter, EV_STRIP_CURLY);
00067             bind_and_queue(executor, caller, enactor, command, objstring,
00068                 cargs, ncargs, number);
00069         }
00070     }
00071     if (key & DOLIST_NOTIFY)
00072     {
00073         char *tbuf = alloc_lbuf("dolist.notify_cmd");
00074         strcpy(tbuf, "@notify/quiet me");
00075         CLinearTimeAbsolute lta;
00076         wait_que(executor, caller, enactor, false, lta, NOTHING, A_SEMAPHORE,
00077             tbuf, cargs, ncargs, mudstate.global_regs);
00078         free_lbuf(tbuf);
00079     }
00080 }
00081 
00082 // Regular @find command
00083 //
00084 void do_find(dbref executor, dbref caller, dbref enactor, int key, char *name)
00085 {
00086     UNUSED_PARAMETER(caller);
00087     UNUSED_PARAMETER(enactor);
00088     UNUSED_PARAMETER(key);
00089 
00090     char *buff;
00091 
00092     if (!payfor(executor, mudconf.searchcost))
00093     {
00094         buff = tprintf("You don't have enough %s.", mudconf.many_coins);
00095         notify_quiet(executor, buff);
00096         return;
00097     }
00098 
00099     dbref i, low_bound, high_bound;
00100     parse_range(&name, &low_bound, &high_bound);
00101     for (i = low_bound; i <= high_bound; i++)
00102     {
00103         if (  (Typeof(i) != TYPE_EXIT)
00104            && Controls(executor, i)
00105            && (!*name || string_match(PureName(i), name)))
00106         {
00107             buff = unparse_object(executor, i, false);
00108             notify(executor, buff);
00109             free_lbuf(buff);
00110         }
00111     }
00112     notify(executor, "***End of List***");
00113 }
00114 
00115 // ---------------------------------------------------------------------------
00116 // get_stats, do_stats: Get counts of items in the db.
00117 //
00118 bool get_stats(dbref player, dbref who, STATS *info)
00119 {
00120     // Do we have permission?
00121     //
00122     if (Good_obj(who) && !Controls(player, who) && !Stat_Any(player))
00123     {
00124         notify(player, NOPERM_MESSAGE);
00125         return false;
00126     }
00127 
00128     // Can we afford it?
00129     //
00130     if (!payfor(player, mudconf.searchcost))
00131     {
00132         notify(player, tprintf("You don't have enough %s.", mudconf.many_coins));
00133         return false;
00134     }
00135     info->s_total = 0;
00136     info->s_rooms = 0;
00137     info->s_exits = 0;
00138     info->s_things = 0;
00139     info->s_players = 0;
00140     info->s_garbage = 0;
00141 
00142     dbref i;
00143     DO_WHOLE_DB(i)
00144     {
00145         if ((who == NOTHING) || (who == Owner(i)))
00146         {
00147             info->s_total++;
00148             if (Going(i) && (Typeof(i) != TYPE_ROOM))
00149             {
00150                 info->s_garbage++;
00151                 continue;
00152             }
00153             switch (Typeof(i))
00154             {
00155             case TYPE_ROOM:
00156 
00157                 info->s_rooms++;
00158                 break;
00159 
00160             case TYPE_EXIT:
00161 
00162                 info->s_exits++;
00163                 break;
00164 
00165             case TYPE_THING:
00166 
00167                 info->s_things++;
00168                 break;
00169 
00170             case TYPE_PLAYER:
00171 
00172                 info->s_players++;
00173                 break;
00174 
00175             default:
00176 
00177                 info->s_garbage++;
00178             }
00179         }
00180     }
00181     return true;
00182 }
00183 
00184 // Reworked by R'nice
00185 //
00186 void do_stats(dbref executor, dbref caller, dbref enactor, int key, char *name)
00187 {
00188     UNUSED_PARAMETER(caller);
00189     UNUSED_PARAMETER(enactor);
00190 
00191     dbref owner;
00192 
00193     switch (key)
00194     {
00195     case STAT_ALL:
00196 
00197         owner = NOTHING;
00198         break;
00199 
00200     case STAT_ME:
00201 
00202         owner = Owner(executor);
00203         break;
00204 
00205     case STAT_PLAYER:
00206 
00207         if (!(name && *name))
00208         {
00209             int nNextFree = mudstate.freelist;
00210             if (mudstate.freelist == NOTHING)
00211             {
00212                 nNextFree = mudstate.db_top;
00213             }
00214             notify(executor, tprintf("The universe contains %d objects (next free is #%d).",
00215                 mudstate.db_top, nNextFree));
00216             return;
00217         }
00218         owner = lookup_player(executor, name, true);
00219         if (owner == NOTHING)
00220         {
00221             notify(executor, "Not found.");
00222             return;
00223         }
00224         break;
00225 
00226     default:
00227 
00228         notify(executor, "Illegal combination of switches.");
00229         return;
00230     }
00231 
00232     STATS statinfo;
00233     if (!get_stats(executor, owner, &statinfo))
00234     {
00235         return;
00236     }
00237     notify(executor, tprintf(
00238      "%d objects = %d rooms, %d exits, %d things, %d players. (%d garbage)",
00239                statinfo.s_total, statinfo.s_rooms, statinfo.s_exits,
00240                statinfo.s_things, statinfo.s_players,
00241                statinfo.s_garbage));
00242 }
00243 
00244 int chown_all(dbref from_player, dbref to_player, dbref acting_player, int key)
00245 {
00246     if (!isPlayer(from_player))
00247     {
00248         from_player = Owner(from_player);
00249     }
00250     if (!isPlayer(to_player))
00251     {
00252         to_player = Owner(to_player);
00253     }
00254     int count     = 0;
00255     if (  God(from_player)
00256        && !God(acting_player))
00257     {
00258         notify(acting_player, "Permission denied.");
00259     }
00260     else
00261     {
00262         int i;
00263         int quota_out = 0;
00264         int quota_in  = 0;
00265         DO_WHOLE_DB(i)
00266         {
00267             if (  Owner(i) == from_player
00268                && Owner(i) != i)
00269             {
00270                 switch (Typeof(i))
00271                 {
00272                 case TYPE_PLAYER:
00273 
00274                     s_Owner(i, i);
00275                     quota_out += mudconf.player_quota;
00276                     break;
00277 
00278                 case TYPE_THING:
00279 
00280                     s_Owner(i, to_player);
00281                     quota_out += mudconf.thing_quota;
00282                     quota_in -= mudconf.thing_quota;
00283                     break;
00284 
00285                 case TYPE_ROOM:
00286 
00287                     s_Owner(i, to_player);
00288                     quota_out += mudconf.room_quota;
00289                     quota_in -= mudconf.room_quota;
00290                     break;
00291 
00292                 case TYPE_EXIT:
00293 
00294                     s_Owner(i, to_player);
00295                     quota_out += mudconf.exit_quota;
00296                     quota_in -= mudconf.exit_quota;
00297                     break;
00298 
00299                 default:
00300 
00301                     s_Owner(i, to_player);
00302                 }
00303                 s_Flags(i, FLAG_WORD1,
00304                     (Flags(i) & ~(CHOWN_OK | INHERIT)) | HALT);
00305 
00306                 if (key & CHOWN_NOZONE)
00307                 {
00308                     s_Zone(i, NOTHING);
00309                 }
00310                 count++;
00311             }
00312         }
00313         add_quota(from_player, quota_out);
00314         add_quota(to_player, quota_in);
00315     }
00316     return count;
00317 }
00318 
00319 void do_chownall
00320 (
00321     dbref executor,
00322     dbref caller,
00323     dbref enactor,
00324     int   key,
00325     int   nargs,
00326     char *from,
00327     char *to
00328 )
00329 {
00330     UNUSED_PARAMETER(caller);
00331     UNUSED_PARAMETER(enactor);
00332     UNUSED_PARAMETER(nargs);
00333 
00334     init_match(executor, from, TYPE_PLAYER);
00335     match_neighbor();
00336     match_absolute();
00337     match_player();
00338 
00339     dbref victim = noisy_match_result();
00340     if (NOTHING == victim)
00341     {
00342         return;
00343     }
00344     else if (!isPlayer(victim))
00345     {
00346         notify(executor, "Victim must be a player.");
00347         return;
00348     }
00349 
00350     dbref recipient = executor;
00351     if (  NULL  != to
00352        && to[0] != '\0')
00353     {
00354         init_match(executor, to, TYPE_PLAYER);
00355         match_neighbor();
00356         match_absolute();
00357         match_player();
00358         recipient = noisy_match_result();
00359         if (NOTHING == recipient)
00360         {
00361             return;
00362         }
00363     }
00364 
00365     int count = chown_all(victim, recipient, executor, key);
00366     if (!Quiet(executor))
00367     {
00368         notify(executor, tprintf("%d objects @chowned.", count));
00369     }
00370 }
00371 
00372 #define ANY_OWNER -2
00373 
00374 static void er_mark_disabled(dbref player)
00375 {
00376     notify(player,
00377      "The mark commands are not allowed while DB cleaning is enabled.");
00378     notify(player,
00379      "Use the '@disable cleaning' command to disable automatic cleaning.");
00380     notify(player,
00381      "Remember to '@unmark_all' before re-enabling automatic cleaning.");
00382 }
00383 
00384 
00385 // ---------------------------------------------------------------------------
00386 // do_search: Walk the db reporting various things (or setting/clearing mark
00387 // bits)
00388 //
00389 bool search_setup(dbref player, char *searchfor, SEARCH *parm)
00390 {
00391     // Crack arg into <pname> <type>=<targ>,<low>,<high>
00392     //
00393     char *pname = parse_to(&searchfor, '=', EV_STRIP_TS);
00394     if (!pname || !*pname)
00395     {
00396         pname = "me";
00397     }
00398     else
00399     {
00400         mux_strlwr(pname);
00401     }
00402 
00403     char *searchtype;
00404     if (searchfor && *searchfor)
00405     {
00406         searchtype = strrchr(pname, ' ');
00407         if (searchtype)
00408         {
00409             *searchtype++ = '\0';
00410         }
00411         else
00412         {
00413             searchtype = pname;
00414             pname = "";
00415         }
00416     }
00417     else
00418     {
00419         searchtype = "";
00420     }
00421 
00422     // If the player name is quoted, strip the quotes.
00423     //
00424     if (*pname == '\"')
00425     {
00426         size_t k = strlen(pname) - 1;
00427         if (pname[k] == '"')
00428         {
00429             pname[k] = '\0';
00430             pname++;
00431         }
00432     }
00433 
00434     // Strip any range arguments.
00435     //
00436     parse_range(&searchfor, &parm->low_bound, &parm->high_bound);
00437 
00438 
00439     // Set limits on who we search.
00440     //
00441     parm->s_owner = Owner(player);
00442     parm->s_wizard = Search(player);
00443     parm->s_rst_owner = NOTHING;
00444     if (!*pname)
00445     {
00446         parm->s_rst_owner = parm->s_wizard ? ANY_OWNER : player;
00447     }
00448     else if (pname[0] == '#')
00449     {
00450         parm->s_rst_owner = mux_atol(&pname[1]);
00451         if (!Good_obj(parm->s_rst_owner))
00452         {
00453             parm->s_rst_owner = NOTHING;
00454         }
00455         else if (Typeof(parm->s_rst_owner) != TYPE_PLAYER)
00456         {
00457             parm->s_rst_owner = NOTHING;
00458         }
00459 
00460     }
00461     else if (strcmp(pname, "me") == 0)
00462     {
00463         parm->s_rst_owner = player;
00464     }
00465     else
00466     {
00467         parm->s_rst_owner = lookup_player(player, pname, true);
00468     }
00469 
00470     if (parm->s_rst_owner == NOTHING)
00471     {
00472         notify(player, tprintf("%s: No such player", pname));
00473         return false;
00474     }
00475 
00476     // Set limits on what we search for.
00477     //
00478     int err = 0;
00479     parm->s_rst_name = NULL;
00480     parm->s_rst_eval = NULL;
00481     parm->s_rst_type = NOTYPE;
00482     parm->s_parent = NOTHING;
00483     parm->s_zone = NOTHING;
00484     for (int i = FLAG_WORD1; i <= FLAG_WORD3; i++)
00485     {
00486         parm->s_fset.word[i] = 0;
00487     }
00488     parm->s_pset.word1 = 0;
00489     parm->s_pset.word2 = 0;
00490 
00491     switch (searchtype[0])
00492     {
00493     case '\0':
00494 
00495         // The no class requested class  :)
00496         //
00497         break;
00498 
00499     case 'e':
00500 
00501         if (string_prefix("exits", searchtype))
00502         {
00503             parm->s_rst_name = searchfor;
00504             parm->s_rst_type = TYPE_EXIT;
00505         }
00506         else if (string_prefix("evaluate", searchtype))
00507         {
00508             parm->s_rst_eval = searchfor;
00509         }
00510         else if (string_prefix("eplayer", searchtype))
00511         {
00512             parm->s_rst_type = TYPE_PLAYER;
00513             parm->s_rst_eval = searchfor;
00514         }
00515         else if (string_prefix("eroom", searchtype))
00516         {
00517             parm->s_rst_type = TYPE_ROOM;
00518             parm->s_rst_eval = searchfor;
00519         }
00520         else if (string_prefix("eobject", searchtype))
00521         {
00522             parm->s_rst_type = TYPE_THING;
00523             parm->s_rst_eval = searchfor;
00524         }
00525         else if (string_prefix("ething", searchtype))
00526         {
00527             parm->s_rst_type = TYPE_THING;
00528             parm->s_rst_eval = searchfor;
00529         }
00530         else if (string_prefix("eexit", searchtype))
00531         {
00532             parm->s_rst_type = TYPE_EXIT;
00533             parm->s_rst_eval = searchfor;
00534         }
00535         else
00536         {
00537             err = 1;
00538         }
00539         break;
00540 
00541     case 'f':
00542 
00543         if (string_prefix("flags", searchtype))
00544         {
00545             // convert_flags ignores previous values of flag_mask and
00546             // s_rst_type while setting them.
00547             //
00548             if ( !convert_flags( player, searchfor, &parm->s_fset,
00549                                 &parm->s_rst_type) )
00550             {
00551                 return false;
00552             }
00553         }
00554         else
00555         {
00556             err = 1;
00557         }
00558         break;
00559 
00560     case 'n':
00561 
00562         if (string_prefix("name", searchtype))
00563         {
00564             parm->s_rst_name = searchfor;
00565         }
00566         else
00567         {
00568             err = 1;
00569         }
00570         break;
00571 
00572     case 'o':
00573 
00574         if (string_prefix("objects", searchtype))
00575         {
00576             parm->s_rst_name = searchfor;
00577             parm->s_rst_type = TYPE_THING;
00578         }
00579         else
00580         {
00581             err = 1;
00582         }
00583         break;
00584 
00585     case 'p':
00586 
00587         if (string_prefix("players", searchtype))
00588         {
00589             parm->s_rst_name = searchfor;
00590             parm->s_rst_type = TYPE_PLAYER;
00591             if (!*pname)
00592             {
00593                 parm->s_rst_owner = ANY_OWNER;
00594             }
00595         }
00596         else if (string_prefix("parent", searchtype))
00597         {
00598             parm->s_parent = match_controlled(player, searchfor);
00599             if (!Good_obj(parm->s_parent))
00600             {
00601                 return false;
00602             }
00603             if (!*pname)
00604             {
00605                 parm->s_rst_owner = ANY_OWNER;
00606             }
00607         }
00608         else if (string_prefix("power", searchtype))
00609         {
00610             if (!decode_power(player, searchfor, &parm->s_pset))
00611             {
00612                 return false;
00613             }
00614         }
00615         else
00616         {
00617             err = 1;
00618         }
00619         break;
00620 
00621     case 'r':
00622 
00623         if (string_prefix("rooms", searchtype))
00624         {
00625             parm->s_rst_name = searchfor;
00626             parm->s_rst_type = TYPE_ROOM;
00627         }
00628         else
00629         {
00630             err = 1;
00631         }
00632         break;
00633 
00634     case 't':
00635 
00636         if (string_prefix("type", searchtype))
00637         {
00638             if (searchfor[0] == '\0')
00639             {
00640                 break;
00641             }
00642             if (string_prefix("rooms", searchfor))
00643             {
00644                 parm->s_rst_type = TYPE_ROOM;
00645             }
00646             else if (string_prefix("exits", searchfor))
00647             {
00648                 parm->s_rst_type = TYPE_EXIT;
00649             }
00650             else if (string_prefix("objects", searchfor))
00651             {
00652                 parm->s_rst_type = TYPE_THING;
00653             }
00654             else if (string_prefix("things", searchfor))
00655             {
00656                 parm->s_rst_type = TYPE_THING;
00657             }
00658             else if (string_prefix("garbage", searchfor))
00659             {
00660                 parm->s_rst_type = TYPE_GARBAGE;
00661             }
00662             else if (string_prefix("players", searchfor))
00663             {
00664                 parm->s_rst_type = TYPE_PLAYER;
00665                 if (!*pname)
00666                 {
00667                     parm->s_rst_owner = ANY_OWNER;
00668                 }
00669             }
00670             else
00671             {
00672                 notify(player, tprintf("%s: unknown type", searchfor));
00673                 return false;
00674             }
00675         }
00676         else if (string_prefix("things", searchtype))
00677         {
00678             parm->s_rst_name = searchfor;
00679             parm->s_rst_type = TYPE_THING;
00680         }
00681         else
00682         {
00683             err = 1;
00684         }
00685         break;
00686 
00687     case 'z':
00688 
00689         if (string_prefix("zone", searchtype))
00690         {
00691             parm->s_zone = match_controlled(player, searchfor);
00692             if (!Good_obj(parm->s_zone))
00693             {
00694                 return false;
00695             }
00696             if (!*pname)
00697             {
00698                 parm->s_rst_owner = ANY_OWNER;
00699             }
00700         }
00701         else
00702         {
00703             err = 1;
00704         }
00705         break;
00706 
00707     default:
00708 
00709         err = 1;
00710     }
00711 
00712     if (err)
00713     {
00714         notify(player, tprintf("%s: unknown class", searchtype));
00715         return false;
00716     }
00717 
00718     // Make sure player is authorized to do the search.
00719     //
00720     if (  !parm->s_wizard
00721        && (parm->s_rst_type != TYPE_PLAYER)
00722        && (parm->s_rst_owner != player)
00723        && (parm->s_rst_owner != ANY_OWNER))
00724     {
00725         notify(player, "You need a search warrant to do that!");
00726         return false;
00727     }
00728 
00729     // Make sure player has money to do the search.
00730     //
00731     if (!payfor(player, mudconf.searchcost))
00732     {
00733         notify(player,
00734             tprintf("You don't have enough %s to search. (You need %d)",
00735                  mudconf.many_coins, mudconf.searchcost));
00736         return false;
00737     }
00738     return true;
00739 }
00740 
00741 void search_perform(dbref executor, dbref caller, dbref enactor, SEARCH *parm)
00742 {
00743     POWER thing1powers, thing2powers;
00744     char *result, *bp, *str;
00745 
00746     char *buff = alloc_sbuf("search_perform.num");
00747     int save_invk_ctr = mudstate.func_invk_ctr;
00748 
00749     dbref thing;
00750     for (thing = parm->low_bound; thing <= parm->high_bound; thing++)
00751     {
00752         mudstate.func_invk_ctr = save_invk_ctr;
00753 
00754         // Check for matching type.
00755         //
00756         if (  (parm->s_rst_type != NOTYPE)
00757            && (parm->s_rst_type != Typeof(thing)))
00758         {
00759             continue;
00760         }
00761 
00762         // Check for matching owner.
00763         //
00764         if (  (parm->s_rst_owner != ANY_OWNER)
00765            && (parm->s_rst_owner != Owner(thing)))
00766         {
00767             continue;
00768         }
00769 
00770         // Toss out destroyed things.
00771         //
00772         if (Going(thing))
00773         {
00774             continue;
00775         }
00776 
00777         // Check for matching parent.
00778         //
00779         if (  (parm->s_parent != NOTHING)
00780            && (parm->s_parent != Parent(thing)))
00781         {
00782             continue;
00783         }
00784 
00785         // Check for matching zone.
00786         //
00787         if (  (parm->s_zone != NOTHING)
00788            && (parm->s_zone != Zone(thing)))
00789         {
00790             continue;
00791         }
00792 
00793         // Check for matching flags.
00794         //
00795         bool b = false;
00796         for (int i = FLAG_WORD1; i <= FLAG_WORD3; i++)
00797         {
00798             FLAG f = parm->s_fset.word[i];
00799             if ((db[thing].fs.word[i] & f) != f)
00800             {
00801                 b = true;
00802                 break;
00803             }
00804         }
00805         if (b)
00806         {
00807             continue;
00808         }
00809 
00810         // Check for matching power.
00811         //
00812         thing1powers = Powers(thing);
00813         thing2powers = Powers2(thing);
00814         if ((thing1powers & parm->s_pset.word1) != parm->s_pset.word1)
00815         {
00816             continue;
00817         }
00818         if ((thing2powers & parm->s_pset.word2) != parm->s_pset.word2)
00819         {
00820             continue;
00821         }
00822 
00823         // Check for matching name.
00824         //
00825         if (parm->s_rst_name != NULL)
00826         {
00827             if (!string_prefix(PureName(thing), parm->s_rst_name))
00828                 continue;
00829         }
00830 
00831         // Check for successful evaluation.
00832         //
00833         if (parm->s_rst_eval != NULL)
00834         {
00835             buff[0] = '#';
00836             mux_ltoa(thing, buff+1);
00837             char *buff2 = replace_tokens(parm->s_rst_eval, buff, NULL, NULL);
00838             result = bp = alloc_lbuf("search_perform");
00839             str = buff2;
00840             mux_exec(result, &bp, executor, caller, enactor,
00841                 EV_FCHECK | EV_EVAL | EV_NOTRACE, &str, (char **)NULL, 0);
00842             *bp = '\0';
00843             free_lbuf(buff2);
00844             if (!*result || !xlate(result))
00845             {
00846                 free_lbuf(result);
00847                 continue;
00848             }
00849             free_lbuf(result);
00850         }
00851 
00852         // It passed everything. Amazing.
00853         //
00854         olist_add(thing);
00855     }
00856     free_sbuf(buff);
00857     mudstate.func_invk_ctr = save_invk_ctr;
00858 }
00859 
00860 static void search_mark(dbref player, int key)
00861 {
00862     dbref thing;
00863     bool is_marked;
00864 
00865     int nchanged = 0;
00866     for (thing = olist_first(); thing != NOTHING; thing = olist_next())
00867     {
00868         is_marked = Marked(thing);
00869 
00870         // Don't bother checking if marking and already marked (or if
00871         // unmarking and not marked)
00872         //
00873         if (  ((key == SRCH_MARK) && is_marked)
00874            || ((key == SRCH_UNMARK) && !is_marked))
00875         {
00876             continue;
00877         }
00878 
00879         // Toggle the mark bit and update the counters.
00880         //
00881         if (key == SRCH_MARK)
00882         {
00883             Mark(thing);
00884             nchanged++;
00885         }
00886         else
00887         {
00888             Unmark(thing);
00889             nchanged++;
00890         }
00891     }
00892     notify( player, tprintf("%d objects %smarked", nchanged,
00893             ((key == SRCH_MARK) ? "" : "un")) );
00894     return;
00895 }
00896 
00897 void do_search(dbref executor, dbref caller, dbref enactor, int key, char *arg)
00898 {
00899     char *buff, *outbuf, *bp;
00900     dbref thing, from, to;
00901     SEARCH searchparm;
00902 
00903     if ((key != SRCH_SEARCH) && (mudconf.control_flags & CF_DBCHECK))
00904     {
00905         er_mark_disabled(executor);
00906         return;
00907     }
00908     if (!search_setup(executor, arg, &searchparm))
00909     {
00910         return;
00911     }
00912     olist_push();
00913     search_perform(executor, caller, enactor, &searchparm);
00914     bool destitute = true;
00915     bool flag;
00916 
00917     // If we are doing a @mark command, handle that here.
00918     //
00919     if (key != SRCH_SEARCH)
00920     {
00921         search_mark(executor, key);
00922         olist_pop();
00923         return;
00924     }
00925     outbuf = alloc_lbuf("do_search.outbuf");
00926 
00927     int rcount = 0;
00928     int ecount = 0;
00929     int tcount = 0;
00930     int pcount = 0;
00931 
00932     // Room search.
00933     //
00934     if (  searchparm.s_rst_type == TYPE_ROOM
00935        || searchparm.s_rst_type == NOTYPE)
00936     {
00937         flag = true;
00938         for (thing = olist_first(); thing != NOTHING; thing = olist_next())
00939         {
00940             if (Typeof(thing) != TYPE_ROOM)
00941             {
00942                 continue;
00943             }
00944             if (flag)
00945             {
00946                 flag = false;
00947                 destitute = false;
00948                 notify(executor, "\nROOMS:");
00949             }
00950             buff = unparse_object(executor, thing, false);
00951             notify(executor, buff);
00952             free_lbuf(buff);
00953             rcount++;
00954         }
00955     }
00956 
00957     // Exit search.
00958     //
00959     if (  searchparm.s_rst_type == TYPE_EXIT
00960        || searchparm.s_rst_type == NOTYPE)
00961     {
00962         flag = true;
00963         for (thing = olist_first(); thing != NOTHING; thing = olist_next())
00964         {
00965             if (Typeof(thing) != TYPE_EXIT)
00966             {
00967                 continue;
00968             }
00969             if (flag)
00970             {
00971                 flag = false;
00972                 destitute = false;
00973                 notify(executor, "\nEXITS:");
00974             }
00975             from = Exits(thing);
00976             to = Location(thing);
00977 
00978             bp = outbuf;
00979             buff = unparse_object(executor, thing, false);
00980             safe_str(buff, outbuf, &bp);
00981             free_lbuf(buff);
00982 
00983             safe_str(" [from ", outbuf, &bp);
00984             buff = unparse_object(executor, from, false);
00985             safe_str(((from == NOTHING) ? "NOWHERE" : buff), outbuf, &bp);
00986             free_lbuf(buff);
00987 
00988             safe_str(" to ", outbuf, &bp);
00989             buff = unparse_object(executor, to, false);
00990             safe_str(((to == NOTHING) ? "NOWHERE" : buff), outbuf, &bp);
00991             free_lbuf(buff);
00992 
00993             safe_chr(']', outbuf, &bp);
00994             *bp = '\0';
00995             notify(executor, outbuf);
00996             ecount++;
00997         }
00998     }
00999 
01000     // Object search
01001     //
01002     if (  searchparm.s_rst_type == TYPE_THING
01003        || searchparm.s_rst_type == NOTYPE)
01004     {
01005         flag = true;
01006         for (thing = olist_first(); thing != NOTHING; thing = olist_next())
01007         {
01008             if (Typeof(thing) != TYPE_THING)
01009             {
01010                 continue;
01011             }
01012             if (flag)
01013             {
01014                 flag = false;
01015                 destitute = false;
01016                 notify(executor, "\nOBJECTS:");
01017             }
01018             bp = outbuf;
01019             buff = unparse_object(executor, thing, false);
01020             safe_str(buff, outbuf, &bp);
01021             free_lbuf(buff);
01022 
01023             safe_str(" [owner: ", outbuf, &bp);
01024             buff = unparse_object(executor, Owner(thing), false);
01025             safe_str(buff, outbuf, &bp);
01026             free_lbuf(buff);
01027 
01028             safe_chr(']', outbuf, &bp);
01029             *bp = '\0';
01030             notify(executor, outbuf);
01031             tcount++;
01032         }
01033     }
01034 
01035     // Player search
01036     //
01037     if (  searchparm.s_rst_type == TYPE_PLAYER
01038        || searchparm.s_rst_type == NOTYPE)
01039     {
01040         flag = true;
01041         for (thing = olist_first(); thing != NOTHING; thing = olist_next())
01042         {
01043             if (Typeof(thing) != TYPE_PLAYER)
01044             {
01045                 continue;
01046             }
01047             if (flag)
01048             {
01049                 flag = false;
01050                 destitute = false;
01051                 notify(executor, "\nPLAYERS:");
01052             }
01053             bp = outbuf;
01054             buff = unparse_object(executor, thing, 0);
01055             safe_str(buff, outbuf, &bp);
01056             free_lbuf(buff);
01057             if (searchparm.s_wizard)
01058             {
01059                 safe_str(" [location: ", outbuf, &bp);
01060                 buff = unparse_object(executor, Location(thing), false);
01061                 safe_str(buff, outbuf, &bp);
01062                 free_lbuf(buff);
01063                 safe_chr(']', outbuf, &bp);
01064             }
01065             *bp = '\0';
01066             notify(executor, outbuf);
01067             pcount++;
01068         }
01069     }
01070 
01071     // If nothing found matching search criteria.
01072     //
01073     if (destitute)
01074     {
01075         notify(executor, "Nothing found.");
01076     }
01077     else
01078     {
01079         sprintf(outbuf,
01080             "\nFound:  Rooms...%d  Exits...%d  Objects...%d  Players...%d",
01081             rcount, ecount, tcount, pcount);
01082         notify(executor, outbuf);
01083     }
01084     free_lbuf(outbuf);
01085     olist_pop();
01086 }
01087 
01088 // ---------------------------------------------------------------------------
01089 // do_markall: set or clear the mark bits of all objects in the db.
01090 //
01091 void do_markall(dbref executor, dbref caller, dbref enactor, int key)
01092 {
01093     UNUSED_PARAMETER(caller);
01094     UNUSED_PARAMETER(enactor);
01095 
01096     int i;
01097 
01098     if (mudconf.control_flags & CF_DBCHECK)
01099     {
01100         er_mark_disabled(executor);
01101         return;
01102     }
01103     if (key == MARK_SET)
01104     {
01105         Mark_all(i);
01106     }
01107     else if (key == MARK_CLEAR)
01108     {
01109         Unmark_all(i);
01110     }
01111     if (!Quiet(executor))
01112     {
01113         notify(executor, "Done.");
01114     }
01115 }
01116 
01117 // ---------------------------------------------------------------------------
01118 // do_apply_marked: Perform a command for each marked obj in the db.
01119 //
01120 void do_apply_marked( dbref executor, dbref caller, dbref enactor, int key,
01121                       char *command, char *cargs[], int ncargs)
01122 {
01123     UNUSED_PARAMETER(key);
01124 
01125     if (mudconf.control_flags & CF_DBCHECK)
01126     {
01127         er_mark_disabled(executor);
01128         return;
01129     }
01130     char *buff = alloc_sbuf("do_apply_marked");
01131     int i;
01132     int number = 0;
01133     DO_WHOLE_DB(i)
01134     {
01135         if (Marked(i))
01136         {
01137             buff[0] = '#';
01138             mux_ltoa(i, buff+1);
01139             number++;
01140             bind_and_queue(executor, caller, enactor, command, buff,
01141                 cargs, ncargs, number);
01142         }
01143     }
01144     free_sbuf(buff);
01145     if (!Quiet(executor))
01146     {
01147         notify(executor, "Done.");
01148     }
01149 }
01150 
01151 // ---------------------------------------------------------------------------
01152 // Object list management routines: olist_push, olist_pop, olist_add,
01153 //   olist_first, olist_next
01154 //
01155 
01156 // olist_push: Create a new object list at the top of the object list stack.
01157 //
01158 void olist_push(void)
01159 {
01160     OLSTK *ol = (OLSTK *)MEMALLOC(sizeof(OLSTK));
01161     ISOUTOFMEMORY(ol);
01162     ol->next = mudstate.olist;
01163     mudstate.olist = ol;
01164 
01165     ol->head = NULL;
01166     ol->tail = NULL;
01167     ol->cblock = NULL;
01168     ol->count = 0;
01169     ol->citm = 0;
01170 }
01171 
01172 // olist_pop: Pop one entire list off the object list stack.
01173 //
01174 void olist_pop(void)
01175 {
01176     OLSTK *ol = mudstate.olist->next;
01177     OBLOCK *op, *onext;
01178     for (op = mudstate.olist->head; op != NULL; op = onext)
01179     {
01180         onext = op->next;
01181         free_lbuf(op);
01182     }
01183     MEMFREE(mudstate.olist);
01184     mudstate.olist = ol;
01185 }
01186 
01187 // olist_add: Add an entry to the object list.
01188 //
01189 void olist_add(dbref item)
01190 {
01191     OBLOCK *op;
01192 
01193     if (!mudstate.olist->head)
01194     {
01195         op = (OBLOCK *) alloc_lbuf("olist_add.first");
01196         mudstate.olist->head = mudstate.olist->tail = op;
01197         mudstate.olist->count = 0;
01198         op->next = NULL;
01199     }
01200     else if (mudstate.olist->count >= OBLOCK_SIZE)
01201     {
01202         op = (OBLOCK *) alloc_lbuf("olist_add.next");
01203         mudstate.olist->tail->next = op;
01204         mudstate.olist->tail = op;
01205         mudstate.olist->count = 0;
01206         op->next = NULL;
01207     }
01208     else
01209     {
01210         op = mudstate.olist->tail;
01211     }
01212     op->data[mudstate.olist->count++] = item;
01213 }
01214 
01215 // olist_first: Return the first entry in the object list.
01216 //
01217 dbref olist_first(void)
01218 {
01219     if (!mudstate.olist->head)
01220     {
01221         return NOTHING;
01222     }
01223     if (  (mudstate.olist->head == mudstate.olist->tail)
01224        && (mudstate.olist->count == 0))
01225     {
01226         return NOTHING;
01227     }
01228     mudstate.olist->cblock = mudstate.olist->head;
01229     mudstate.olist->citm = 0;
01230     return mudstate.olist->cblock->data[mudstate.olist->citm++];
01231 }
01232 
01233 dbref olist_next(void)
01234 {
01235     if (!mudstate.olist->cblock)
01236     {
01237         return NOTHING;
01238     }
01239     if (  (mudstate.olist->cblock == mudstate.olist->tail)
01240        && (mudstate.olist->citm >= mudstate.olist->count))
01241     {
01242         return NOTHING;
01243     }
01244     dbref thing = mudstate.olist->cblock->data[mudstate.olist->citm++];
01245     if (mudstate.olist->citm >= OBLOCK_SIZE)
01246     {
01247         mudstate.olist->cblock = mudstate.olist->cblock->next;
01248         mudstate.olist->citm = 0;
01249     }
01250     return thing;
01251 }

Generated on Mon May 28 04:40:12 2007 for MUX by  doxygen 1.4.7