/************************************************************************** ** Dirt IV System functions ** 1996 - Marty ** Original code by various other Coders **************************************************************************/ #define SYSTEM_C /************************************************************************** ** IMPORT **************************************************************************/ #include <strings.h> #include <unistd.h> #include <stdio.h> #include <signal.h> #include "kernel.h" #include "bprintf.h" #include "main.h" #include "sendsys.h" #include "mudmacros.h" #include "pflags.h" #include "oflags.h" #include "lflags.h" #include "cflags.h" #include "sflags.h" #include "bprintf.h" #include "parse.h" #include "colors.h" #include "zones.h" #include "objsys.h" #include "mobile.h" #include "rooms.h" #include "log.h" #include "main.h" #include "calendar.h" #include "special.h" #include "atsys.h" #include "actions.h" #include "wizard.h" #ifdef INTERMUD #include "InterMud/intermud.h" #endif #ifdef ABERCHAT extern int aberfd; extern Boolean auto_restart; #endif /************************************************************************** ** PROTOTYPES **************************************************************************/ PUBLIC A_COMMAND(delaycom); /* Set the MUD in a delayed reboot */ PUBLIC A_COMMAND(rebootcom); /* Do a direct Reboot of the MUD */ PUBLIC A_COMMAND(updatecom); /* Do a direct Update of the MUD */ PUBLIC A_COMMAND(workloadcom); /* Get the machine's workload and CPU usage */ PUBLIC A_COMMAND(globalcom); /* The the global MUD status */ PUBLIC A_COMMAND(opengamecom); /* Open the game after a shutdown */ PUBLIC A_COMMAND(tournamentcom); /* Open a Tournament on the MUD */ PUBLIC A_COMMAND(startcom); /* Start the mobiles who move */ PUBLIC A_COMMAND(stopcom); /* Stop the mobiles from moving */ PUBLIC A_COMMAND(eventscom); /* Start/Stop events */ PUBLIC A_COMMAND(acctcom); /* Accounting system */ PRIVATE int dopc (int max, int exist); PRIVATE void countmobiles (int zone); PRIVATE void countobjects (int zone); PRIVATE void countrooms (int zone); PUBLIC void objectscom (void); PUBLIC void mstatcom (void); PUBLIC void signalcom (void); /************************************************************************* ** IMPLEMENTATION *************************************************************************/ PUBLIC A_COMMAND(eventscom) { Boolean on; if (brkword() == -1) { bprintf("Usage: events on/off\n"); } else { if (EQ(wordbuf,"on")) { (void)setfunctions(); on = True; } else if (EQ(wordbuf,"off")) { clearfunctions(); on = False; } else { bprintf("Usages: events on/off\n"); return; } send_msg(DEST_ALL,MODE_BRACKET|MODE_QUIET,LVL_DEMI,LVL_MAX,NOBODY,NOBODY, "Game events are %s", on ? "On" : "Off"); #ifdef LOG_EVENTS mudlog("GAME: events %s by %s\n",on ? "ON" : "OFF", pname(mynum)); #endif } } PUBLIC A_COMMAND(delaycom) { if (!ptstflg(mynum,PFL_REBOOT)) { bprintf("You can't do that now.\n"); } else { if (the_world->w_delayed == 0) the_world->w_delayed = 1; else the_world->w_delayed = 0; send_msg (DEST_ALL, MODE_BRACKET|MODE_QUIET, LVL_DEMI, LVL_MAX, NOBODY, NOBODY, "&+wDelayed Reboot now %s", the_world->w_delayed ? "Enabled" : "Disabled" ); mudlog("Delayed Reboot: %s by %s", the_world->w_delayed ? "ENABLED" : "DISABLED", pname(mynum)); } } PUBLIC A_COMMAND(rebootcom) { if (!ptstflg(mynum,PFL_REBOOT)) { erreval(); return; } send_msg(DEST_ALL,MODE_BRACKET,LVL_ARCHWIZARD,LVL_MAX,NOBODY,NOBODY, "World reboot initiated"); numreboots++; #ifdef INTERMUD imShutdown(1); #endif sysreboot(False,False); } PUBLIC A_COMMAND(updatecom) { if (!ptstflg(mynum,PFL_REBOOT)) { erreval(); return; } send_msg(DEST_ALL,MODE_BRACKET,LVL_ARCHWIZARD,LVL_MAX,NOBODY,NOBODY, "World update initiated"); numreboots++; #ifdef INTERMUD imShutdown(1); #endif sysreboot(False,True); } PUBLIC A_COMMAND(workloadcom) { char work[100]; char ps1[100]; char ps2[100]; FILE *fp; char command[50]; char *wlerror = "Unable to get system work load statistics.\n"; if (!ptstflg(mynum,PFL_SYSSTAT)) { erreval(); return; } #ifndef LINUX bprintf ("Disabled for now.\n"); return; #endif sprintf(command,"ps u %d|grep aberd",getpid()); if ((fp = popen ("uptime; ps -u","r")) == NULL ) { bprintf("%s\n",wlerror); return; } fgets (work, sizeof(work),fp); fgets (ps1, sizeof(ps1),fp); pclose (fp); if ((fp = popen(command,"r")) == NULL ) { bprintf("%s",wlerror); return; } fgets(ps2,sizeof(ps2),fp); pclose(fp); bprintf("&+wSystem statistics for server &+w%s&*\n&+w%s&*\n",my_hostname, DOUBLELINE); bprintf("%s\n",work); bprintf("&+w%s Daemon statistics\n",MUDNAME); bprintf("&+w%s&*\n",DOUBLELINE); bprintf("&+w%s",ps1); bprintf("%-79.79s\n",ps2); } PUBLIC A_COMMAND(globalcom) { extern int dnsfd; char buff[80]; bprintf ("&+wGlobal Settings:&*\n&+w%s&*\n" "&+wWeather &+w: &+w%s&*\n", DOUBLELINE, wthr_type (the_world->w_weather)); bprintf ("&+wLock-status &+w: &+w%slocked&*\n", lev2s (buff, the_world->w_lock, 0)); if (the_world->w_start_loc == 0) bprintf ("&+wGame Running &+w: &+wAllowed&*\n"); else bprintf ("&+wGame Running &+w: &+wBlocked &+w(Start Location: &+w%s&+w)&*\n", showname(the_world->w_start_loc)); bprintf ("&+wMUD DNS Status &+w: %s\n", (dnsfd != -1) ? "&+wActivated" : "&+wDown"); #ifdef INTERMUD bprintf ("&+wInterMUD Status &+w: %s&*\n", (imfd == -1) ? "&+wConnection closed" : "&+wConnection Established"); #endif #ifdef ABERCHAT bprintf ("&+wAberChat Status &+w: %s &+w(%s&+w)&*\n", (aberfd == -1) ? "&+wConnection closed" : "&+wConnection Established", auto_restart ? "&+wAutomatic Reconnect" : "&+wManual Connect"); #endif bprintf ("&+wMobiles &+w: %s&*\n", (the_world->w_mob_stop) ? "&+wStopped" : "&+wStarted&*"); bprintf ("&+wWar/Peace &+w: %s&*\n", (the_world->w_peace) ? "&+wPeace" : "&+wWar"); bprintf ("&+wTournament-Mode &+w: %s&*\n", (the_world->w_tournament) ? "&+wActivated" : "&+wDeactivated"); bprintf ("&+wDelayed Reboot &+w: %s&*\n", the_world->w_delayed ? "&+wEnabled" : "&+wDisabled" ); bprintf ("&+wMax. Users &+w: &+w%d&*\n", max_players); bprintf ("&+wNumber of Rooms &+w: " "&+w%4d &+wpermanent +&+w%4d &+wwiz-made = &+w%4d&+w (max %d)&*\n", num_const_locs, numloc - num_const_locs, numloc, GLOBAL_MAX_LOCS); bprintf ("&+wNumber of Mobiles &+w: " "&+w%4d &+wpermanent +&+w%4d&+w wiz-made = &+w%4d&+w (max %d)&*\n", num_const_chars - max_players, numchars - num_const_chars, numchars - max_players, GLOBAL_MAX_MOBS); bprintf ("&+wNumber of Objects &+w: " "&+w%4d&+w permanent +&+w%4d&+w wiz-made = &+w%4d&+w (max %d)&+w\n", num_const_obs, numobs - num_const_obs, numobs, GLOBAL_MAX_OBJS); bprintf("&+w%s&*\n",DOUBLELINE); } PUBLIC void shutdowncom (char crash) { FILE *nologin_file; char s[MAX_COM_LEN]; int i; char *t = MUDNAME" is closed for debugging. Please try again later."; if (crash != 100) { if (!ptstflg (mynum, PFL_SHUTDOWN)) { erreval (); return; } } getreinput (s); if (!EMPTY (s)) t = s; if (!crash) { if ((nologin_file = fopen (NOLOGIN, "w")) == NULL) { bprintf ("(Unable to write NOLOGIN file.)"); } else { fprintf (nologin_file, "%s\n", t); fclose (nologin_file); } bprintf ("&+w%s is now closed.&*\n",MUDNAME); send_msg(DEST_ALL,MODE_BRACKET|MODE_QUIET,LVL_MIN,LVL_MAX,mynum,NOBODY, "%s has been closed for the public",MUDNAME); } else { bprintf ("&+w[&+w%s is going down &+wHARD&+w]&*\n",MUDNAME); mudlog ("CRASH Called by %s.",pname(mynum)); rm_pid_file (); } mudlog ("SYSTEM: SHUTDOWN%s by %s", crash ? " >CRASH<" : "", crash == 100 ? "Due to FATAL error" : pname (mynum)); send_msg (DEST_ALL, MODE_BRACKET, LVL_APPREN, LVL_MAX, NOBODY, NOBODY, "%s %s %s", crash ? "CRASH" : "SHUTDOWN", crash == 100 ? "" : "by", crash == 100 ? "DUE TO FATAL ERROR" : pname (mynum)); saveallcom(); /* kick people off here */ for (i = 0; i < max_players; i++) { if (is_in_game (i) && (plev(i) < LVL_GOD && !crash)) { p_crapup (i, t, CRAP_SAVE); } } if (crash) { exit (0); } } PUBLIC A_COMMAND(opengamecom) { if (!ptstflg(mynum, PFL_SHUTDOWN)) { erreval(); return; } if (unlink(NOLOGIN) < 0) { bprintf("The game is already open.\n"); } else { mudlog("SYSTEM: OPENGAME by %s", pname(mynum)); send_msg(DEST_ALL,MODE_QUIET|MODE_BRACKET,LVL_MIN,LVL_MAX,NOBODY,NOBODY, "%s is now open",MUDNAME); } } PUBLIC A_COMMAND(tournamentcom) { bprintf("&+w[&+wTournament mode is now %s&+w]&*\n", (the_world->w_tournament = !the_world->w_tournament) ? "ON" : "OFF"); } PUBLIC A_COMMAND(stopcom) { the_world->w_mob_stop = 1; send_msg (DEST_ALL, MODE_BRACKET|MODE_QUIET, LVL_APPREN, LVL_MAX, NOBODY, NOBODY, "Mobiles STOPped"); mudlog("GAME: mobiles STOPped by %s",pname(mynum)); } PUBLIC A_COMMAND(startcom) { the_world->w_mob_stop = 0; send_msg (DEST_ALL, MODE_BRACKET|MODE_QUIET, LVL_APPREN, LVL_MAX, NOBODY, NOBODY, "Mobiles STARTed"); mudlog("GAME: mobiles STARTed by %s",pname(mynum)); } /** ** The Accounting System - By Illusion **/ PUBLIC A_COMMAND(acctcom) { char text[80]; int zone = -1; int i; if (brkword () != -1) { if ((zone = get_zone_by_name (wordbuf)) == -1) { bprintf ("No Such Zone: %s\n", wordbuf); return; } } if (zone == -1) sprintf (text, "Current System Accounting"); else sprintf (text, "Current System Accounting (Zone: %s)", zname (zone)); for (i = 0; i < (60 - strlen (text)) / 2; ++i) bprintf (" "); bprintf ("&+w%s\n", text); bprintf ("&+w%s\n", DASHLINE); countrooms (zone); bprintf ("\n"); countmobiles (zone); bprintf ("\n"); countobjects (zone); } /* Show percentage: max is maximum, exist is how many of max are left */ PRIVATE int dopc (int max, int exist) { int proc; int t; if (exist > max) /* Someone passed them backwards */ { t = max; /* so we fix that here. */ max = exist; exist = t; } if (!(max)) proc = 0; else proc = (exist * 100) / max; return (proc); } PRIVATE void countmobiles (int zone) { int bas, j = 0, i; int a; int NoHassle, Possessed, DeadMobs; int proc; NoHassle = Possessed = DeadMobs = 0; a = max_players; if (zone == -1) bas = numchars; else { a = 0; bas = znumchars (zone); } for (; a < bas; a++) { i = (zone == -1) ? a : zmob_nr (a, zone); if (EMPTY (pname (i))) continue; if (ptstflg (i, PFL_NOHASSLE)) NoHassle++; if (ptstflg (i, SFL_OCCUPIED)) Possessed++; if (alive (i) != -1) j++; if (zone == -1) DeadMobs = ((numchars - max_players) - j); else DeadMobs = (znumchars (zone) - j); } if (zone == -1) proc = dopc (numchars - max_players, j); else proc = dopc (znumchars (zone), j); if (zone == -1) bprintf ("&+w%-18s: %8d\t%-18s: %8d\n", "Total Mobiles", numchars - max_players, "Living Mobiles", j); else bprintf ("&+w%-18s: %8d\t%-18s: %8d\n", "Total Mobiles", znumchars (zone), "Living Mobiles", j); bprintf ("&+w%-18s: %8d\t%-18s: %8d\n", "Dead Mobiles", DeadMobs, "Percent Living", proc); bprintf ("&+w%-18s: %8d\t%-18s: %8d\n", "Possessed", Possessed, "NoHassle", NoHassle); } PRIVATE void countobjects (int zone) { int proc; long totalval = 0; int aa, oc = 0; int destroyed, weapons, armor, food; int lightable, container, key, noget; int destweap, destarm, destfood, destlight, destcont, destkey; int objnum; destroyed = weapons = armor = food = lightable = container = key = noget = destweap = destarm = destfood = destlight = destcont = destkey = 0; if (zone == -1) objnum = numobs; else { aa = zfirst_obj (zone); objnum = znumobs (zone); } for (aa = 0; aa < objnum; aa++) { if (zone != -1) oc = zobj_nr (aa, zone); if (!otstbit (oc, OFL_NOGET) && !otstbit (oc, OFL_DESTROYED)) totalval += ovalue (oc); if (otstbit (oc, OFL_NOGET)) noget++; if (otstbit (oc, OFL_DESTROYED)) destroyed++; if (otstbit (oc, OFL_WEAPON)) { weapons++; if (otstbit (oc, OFL_DESTROYED)) destweap++; } if (otstbit (oc, OFL_ARMOR)) { armor++; if (otstbit (oc, OFL_DESTROYED)) destarm++; } if (otstbit (oc, OFL_FOOD)) { food++; if (otstbit (oc, OFL_DESTROYED)) destfood++; } if (otstbit (oc, OFL_CONTAINER) && !otstbit (oc, OFL_NOGET)) { container++; if (otstbit (oc, OFL_DESTROYED)) destcont++; } if (otstbit (oc, OFL_KEY)) { key++; if (otstbit (oc, OFL_DESTROYED)) destkey++; } if (otstbit (oc, OFL_LIGHTABLE)) { lightable++; if (otstbit (oc, OFL_DESTROYED)) destlight++; } if (zone == -1) oc++; } if (zone == -1) proc = dopc (oc - destroyed, oc); else proc = dopc (znumobs (zone) - destroyed, znumobs (zone)); if (zone == -1) bprintf ("&+w%-18s: %8d\t%-18s: %8d\n", "Total Objects", oc, "Remaining", oc - destroyed); else bprintf ("&+w%-18s: %8d\t%-18s: %8d\n", "Total Objects", znumobs (zone), "Remaining", znumobs (zone) - destroyed); bprintf ("&+w%-18s: %8d\t%-18s: %8d\n", "Destroyed", destroyed, "Percent Left", proc); bprintf ("&+w%-18s: %8d\t%-18s: %8d\n\n", "NoGet", noget, "Value of Objects", totalval); bprintf ("&+w Detail List of Objects Available to Mortals\n"); bprintf ("&+w%s\n", DASHLINE); bprintf ("&+w%-18s: %8d\t%-18s: %8d\n", "Weapons", weapons, "Destroyed", destweap); bprintf ("&+w%-18s: %8d\t%-18s: %8d\n", "Armor", armor, "Destroyed", destarm); bprintf ("&+w%-18s: %8d\t%-18s: %8d\n", "Food", food, "Destroyed", destfood); bprintf ("&+w%-18s: %8d\t%-18s: %8d\n", "Containers", container, "Destroyed", destcont); bprintf ("&+w%-18s: %8d\t%-18s: %8d\n", "Lightable", lightable, "Destroyed", destlight); bprintf ("&+w%-18s: %8d\t%-18s: %8d\n", "Keys", key, "Destroyed", destkey); bprintf ("&+w%s\n", DASHLINE); } PRIVATE void countrooms (int zone) { int roomct,atcount; if (zone == -1) roomct = num_const_locs; else roomct = znumloc (zone); atcount = countATs(); bprintf ("&+w%-18s: %8d\t%-18s: %8d\n", "Total Rooms", roomct, "Automated Trans.",atcount); } /* objectscom() * 1995 by Illusion * Pager-ized by Marty */ PUBLIC A_COMMAND(objectscom) { int zone = -1; int i, c, oc = 0; char b[60], d[60]; FILE *fp; char fn[512]; if (brkword () != -1) { if ((zone = get_zone_by_name (wordbuf)) == -1) { bprintf ("No Such Zone: %s\n", wordbuf); return; } } sprintf(fn,"%sobjectscom.%s",TEMP_DIR,pname(mynum)); if ((fp = fopen(fn,"w")) == NULL) { fwerror(fn); return; } if (zone == -1) { for (i = 0; i < numobs; ++i) { oc++; c = findzone (oloc (i), b); sprintf (d, "%s%d", b, c); if (ocarrf (i) >= CARRIED_BY) strcpy (d, "Carried"); else if (ocarrf (i) == IN_CONTAINER) strcpy (d, "In Container"); fprintf (fp,"&+w%-12s&+w%-13s", oname (i), d); if (oc % 3 == 0) fprintf (fp,"\n"); } if (oc % 3 != 0) fprintf (fp,"\n"); fprintf (fp,"\n&+wTotal of &+w%d &+wobjects.\n", oc); } else { fprintf (fp,"&+wObject List For Zone: &+w%s\n", zname (zone)); for (i = zfirst_obj (zone); i != SET_END; i = znext_obj (zone)) { oc++; c = findzone (oloc (i), b); sprintf (d, "%s%d", b, c); if (ocarrf (i) >= CARRIED_BY) strcpy (d, "Carried"); else if (ocarrf (i) == IN_CONTAINER) strcpy (d, "In Container"); fprintf (fp,"&+w%-12s&+w%-14s", oname (i), d); if (oc % 3 == 0) fprintf (fp,"\n"); } if (oc % 3 != 0) fprintf (fp,"\n"); fprintf (fp,"\n&+wTotal of &+w%d &+wobjects.\n", oc); } fclose(fp); read_file(fn,NULL,True,NULL); unlink(fn); } /* mstatcom() * Status for mortals * 1995 by Illusion */ PUBLIC A_COMMAND(mstatcom) { int i, j = 0; char cond[50]; char buff[100]; bprintf ("&+wLvl Name Score Str/Max DP AC Cnd Who/Where\n"); bprintf ("&+w--------------------------------------------------------------------------------\n"); for (i = 0; i < max_players; ++i) { if (is_in_game (i) && plev (i) < LVL_APPREN) { ++j; if (pfighting (i) >= 0) sprintf (cond, "&+wFgt &+w%s: %d (%s)", pname (pfighting (i)), pstr (pfighting (i)), xshowname (buff, ploc (i))); else if (phelping (i) >= 0) sprintf (cond, "&+wHlp &+w%s (%s)", pname (phelping (i)), xshowname (buff, ploc (i))); else if (psitting (i)==1) sprintf (cond, "&+wSit &+w(%s)", xshowname (buff, ploc (i))); else if (psitting(i) == 2) sprintf(cond, "&+wSlp &+w(%s)", xshowname(buff,ploc(i))); else if (psitting(i) == 3) sprintf(cond, "&+wTrn &+w(%s)", xshowname(buff,ploc(i))); else sprintf (cond, "&+wStd &+w(%s)", xshowname (buff, ploc (i))); bprintf ("&+w%3d &+w%-13.13s &+w%-6d %s%3d&+w/&+w%-3d &+w%2d %2d &+w%-32.32s\n", plev (i), pname (i), pscore (i), pstr (i) == maxstrength (i) ? "&+w" : pstr (i) < 20 ? "&+w" : "&+w", pstr (i), maxstrength (i), player_damage (i), player_armor (i), cond); } } if (!j) bprintf ("&+w No Mortals On-Line\n"); bprintf ("&+w--------------------------------------------------------------------------------\n"); } PUBLIC A_COMMAND(signalcom) { static char *SigTable[] = {"list", "sigsegv", "sigterm", "sigbus", "sigint", "sigusr1", "sigusr2", TABLE_END}; int sig = -1, x; if (!ptstflg (mynum, PFL_SIGNAL)) { erreval (); return; } if (brkword () == -1) { bprintf ("Send what signal?\n"); return; } if ((x = tlookup (wordbuf, SigTable)) < 0) { bprintf ("Invalid signal.\n"); return; } switch (x) { case 0: sig = -1; break; case 1: sig = SIGSEGV; break; case 2: sig = SIGTERM; break; case 3: sig = SIGBUS; break; case 4: sig = SIGINT; break; case 5: sig = SIGUSR1; break; case 6: sig = SIGUSR2; break; } if (sig == -1) { bprintf ("Signals: SIGSEGV, SIGTERM, SIGBUS, SIGINT, SIGUSR1, SIGUSR2.\n"); return; } send_msg (DEST_ALL, MODE_BRACKET, LVL_ARCHWIZARD, LVL_MAX, mynum, NOBODY, "&+wSignal &*has been called: &+w%s", SigTable[x]); mudlog ("SIGNAL: %s has called signal %s", pname (mynum), SigTable[x]); kill (getpid (), sig); } A_COMMAND(reboot_actions) { char fn[100]; FILE *fp; if (plev(mynum) < LVL_DEMI) { bprintf("Maybe in another time and space.\n"); return; } sprintf(fn,"%s/actions",data_dir); if ((fp = fopen(fn,"r")) == NULL) { bprintf("Unable to locate actions file, reload aborted.\n"); mudlog("FILE: Error opening actions file.\n"); return; } bprintf("Rebooting Action File..\n"); clear_all_ext(); boot_extern(fp,fn); fclose(fp); mudlog("SYSTEM: Actions reloaded by %s",pname(mynum)); send_msg(DEST_ALL,MODE_BRACKET|MODE_QUIET,LVL_ARCHWIZARD,LVL_MAX,mynum,NOBODY, "Actions reloaded by %s",pname(mynum)); bprintf("Actions file has been reloaded.\n"); }