/* ....[@@@..[@@@..............[@.................. MUD++ is a written from ....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and ....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++. ....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing ....[@......[@..[@@@@@..[@@@@@.................. development project. All ................................................ contributions are welcome. ....Copyright(C).1995.Melvin.Smith.............. Enjoy. ------------------------------------------------------------------------------ Melvin Smith (aka Fusion) msmith@hom.net MUD++ development mailing list mudpp@van.ml.org ------------------------------------------------------------------------------ pc_wiz.cc */ #include <sys/time.h> #include <unistd.h> #if !defined(WIN32) #include <sys/resource.h> #endif #include "config.h" #include "string.h" #include "llist.h" #include "room.h" #include "repop.h" #include "hash.h" #include "server.h" #include "area.h" #include "bit.h" #include "screen.h" #include "pc.h" #include "social.h" #include "random.h" #include "cluster.h" #include "global.h" #include "properties.h" #include "persist.h" // This is a utility function which I change often just for debugging // things void PC::do_debug( const String & ) { } void PC::do_shell( const String & arg ) { String arg1; String arg2; arg.startArgs(); arg1 = arg.getArg(); arg2 = arg.getArg(); pcs.remove( this ); shellpcs.addTop( this ); startShell( arg1, arg2 ); } void PC::do_peace( const String & ) { Char * ch; for_each( inRoom()->chars, ch ) if( ch->isFighting() ) ch->stopFighting(); out( "Ok.\n\r" ); } void PC::do_smite( const String & arg ) { PC * victim; if( !arg ) { out( "Smite whom?\n\r" ); return; } victim = getPCWorld( arg ); if( !victim ) { out( "No such person.\n\r" ); return; } victim->out( getShort() ); victim->out( " smites you!\n\rThat really hurt!\n\r...You feel a little groggy.\n\r" ); victim->setOrientation( randgen.get( 1, 3 ) ); victim->setHP( victim->getHP() / 2 ); victim->inRoom()->interp( "** W H A P **\n\r$n smites $N right out of $P boots!!\n\r", this, victim, 0, 0 ); interp( "You smite $N out of $P boots.", this, victim, 0, 0 ); } void PC::do_snoop( const String & arg ) { PC * victim; if( !(bool)arg ) { out( "Snoop whom?\n\r" ); return; } if( arg == "self" || arg == "none" || arg == "off" ) { out( "Snoops off.\n\r" ); if( ( victim = getSnoopVictim() ) ) { victim->setSnooper( 0 ); setSnoopVictim( 0 ); } return; } victim = getPCWorld( arg ); if( !victim ) { out( "No such person.\n\r" ); return; } if( victim == this ) { out( "Can't snoop yourself, think of the bugs that could cause.\n\r" ); return; } if( victim->getLevel() >= getLevel() ) { out( "That person is un-snoopable as far as you are concerned.\n\r" ); return; } if( victim->getSnooper() ) { out( "That person is already being spied on.\n\r" ); return; } victim->setSnooper( this ); setSnoopVictim( victim ); out( "Ok now snooping " ); out( victim->getShort() ); out( ".\n\r" ); } void PC::do_show( const String & arg ) { String str; Host * host; if( !(bool)arg ) { out( "Usage: show { cluster }\n\r" ); return; } if( arg == "cluster" ) { str = "MUD++ cluster information:\n\n\r"; for_each( cluster, host ) { str.sprintfAdd( "%12s %30s %d\n\r", (const char*)host->getName(), (const char*)host->getHost(), host->getPlayerPort() ); } } out( str ); } void PC::do_force( const String & arg ) { arg.startArgs(); String argName = arg.getArg(); String argComd = arg.getArgRest(); // NPCs dont have command parser yet. if( !(bool)argName || !(bool)argComd ) { out( "Usage: force <person> <command string>\n\r" ); return; } PC *plr = getPCWorld( argName ); if( !plr ) { out( argName ); out( " is not playing.\n\r" ); return; } if( plr->getLevel() >= getLevel() ) { out( plr->getName() ); out( " is too powerful for you.\n\r" ); plr->out( getName() ); plr->out( " just tried to force you to " ); plr->out( argComd ); plr->out( " but got denied!\n\r" ); return; } plr->out( getName() ); plr->out( " forces you to " ); plr->out( argComd ); plr->out( ".\n\r" ); plr->command( argComd ); out( "Ok.\n\r" ); } // Just a test to get ident working. Will do non-blocking when // this is done. void PC::do_ident( const String & arg ) { char ip[ 256 ]; char buf[ 256 ]; PC *pc; Socket *identServ; if( !( pc = getPCWorld( arg ) ) ) { out( "No such player connected.\n\r" ); return; } if( !pc->getSocket() ) { out( "That player is currently link dead.\n\r" ); return; } strcpy( ip, pc->getSocket()->getHostName() ); identServ = new Socket( SOCK_STREAM, ip, 113 ); if( identServ->error() ) { out( "Socket error.\n\r" ); delete socket; return; } if( identServ->connect() == -1 ) { out( "Connect error. Ident server may not be running on foreign host.\n\r" ); delete identServ; return; } out( "Connected to ident server on " ); out( identServ->getHostName() ); out( "\n\r" ); int foreign_port = pc->getSocket()->getPort(); int bytes = sprintf( buf, "%d , %d\n\r", foreign_port, 4000 ); identServ->write( buf, bytes ); *buf = 0; while( !*buf ) identServ->read( buf, 256 ); delete identServ; out( buf ); } void PC::do_cat( const String & arg ) { if( !(bool)arg ) return; view( arg.chars() ); } void PC::do_users( const String & ) { String str; PC *pc; LList<PC> tlist = pcs; str = "Name Host Foreign Idle\n\r"; str += " Port \n\r"; for_each( tlist, pc ) { if( pc->getSocket() ) { str.sprintfAdd( "%-15s%-35s%-12d%s\n\r", pc->getName().chars(), pc->getSocket()->getHostName(), pc->getSocket()->getPort(), pc->getIdle() ? itoa(pc->getIdle()) : "" ); } else { str.sprintfAdd( "%-15s%-35s%-12d%s\n\r", pc->getName().chars(), "(*LOST LINK*)", 0, pc->getIdle() ? itoa(pc->getIdle()) : "" ); } } out( str ); } void PC::do_echo( const String & arg ) { String str; str << "\n\n\r" << arg << "\n\r"; outAllCharExcept( str, 0, 0 ); } void PC::do_immtalk( const String & arg ) { PC *ch; LList<PC> tlist = pcs; String str; if( !(bool)arg ) { out( "Immtalk what?\n\r" ); return; } str << BYELLOW << name << " : " << arg << "\n\r" << NTEXT; for_each( tlist, ch ) { if( ch->isPlaying() ) { if( ch != this ) ch->out( "\n\r" ); ch->out( str ); } } } void PC::do_advance( const String & arg ) { arg.startArgs(); String argName = arg.getArg(); String argLevel = arg.getArg(); if( !(bool)argName || !(bool)argLevel ) { out( "Usage: advance <person> <level>\n\r" ); return; } PC *plr = getPCWorld( argName ); if( !plr ) { out( argName ); out( " is not online.\n\r" ); return; } int lev = argLevel.asInt(); if( lev < 1 || lev > MAX_PC_LEVEL ) { out( "No can do.\n\r" ); return; } // Need to check levels here. plr->advance( lev - plr->getLevel() ); out( "Ok.\n\r" ); } void PC::do_memory( const String & ) { String str; str << "NUMBER OF" <<endl; str.sprintfAdd("Objects: %6d Rooms: %6d\n\r", Object::getTotalCount() ,Room::getTotalCount() ); str.sprintfAdd("NPCs: %6d Repops: %6d\n\r", NPC::getTotalCount(), Repop::getTotalCount() ); str.sprintfAdd("PCs: %6d Affects: %6d\n\r", PC::getTotalCount(), Affect::getTotalCount() ); str << "Actions: " << Action::getTotalCount() << endl; str << "LList nodes (used/allocated): " << Node::allocated_nodes - Node::getFreeCount() << '/' << Node::allocated_nodes << endl; str << endl; #if !defined(WIN32) struct rusage use; getrusage( RUSAGE_SELF, &use ); str << "Usage of resources:" << endl; str << "User time: "<< use.ru_utime.tv_sec << "s " << (use.ru_utime.tv_usec/1000) << "ms " <<endl; str << "System time: "<< use.ru_stime.tv_sec << "s " << (use.ru_stime.tv_usec/1000) << "ms " <<endl; str << "Page reclaims/faults: "<< use.ru_minflt <<'/'<< use.ru_majflt << endl; getrusage( RUSAGE_CHILDREN, &use ); str << "Same for children:" << endl; str << "User time: "<< use.ru_utime.tv_sec << "s " << (use.ru_utime.tv_usec/1000) << "ms " <<endl; str << "System time: "<< use.ru_stime.tv_sec << "s " << (use.ru_stime.tv_usec/1000) << "ms " <<endl; str << "Page reclaims/faults: "<< use.ru_minflt <<'/'<< use.ru_majflt << endl; #endif //WIN32 out(str); /* str << "Maximum resident set size: " << use.ru_maxrss <<endl; str << "Shared memory size: " << use.ru_ixrss << endl; str << "Data memory size: " << use.ru_idrss << endl; str << "Stack memory size: " << use.ru_isrss << endl; str << "Maximum resident set size: " << use.ru_maxrss <<endl; str << "Shared memory size: " << use.ru_ixrss << endl; str << "Data memory size: " << use.ru_idrss << endl; str << "Stack memory size: " << use.ru_isrss << endl; */ } void GC_dump(); int GC_run(); void PC::do_gc( const String & args ) { if ( args == "dump" ) { GC_dump(); out ( "Garbage collector stack dumped.\n\r"); } else if ( args == "run" ) { String str; str << "Garbage collected " << GC_run() << " VMObjects.\n\r"; out(str); } else if ( args == "hint" ) { String str; str.sprintf("Current (used gc stack)/(gc stack size) is %d/%d\n\r", GC_getStackSize() - GC_getFreeCount() ,GC_getStackSize() ); str.sprintfAdd("Previous run (used gc stack)/(gc stack size) were %d/%d\n\r", GC_stack_hint - GC_free_hint , GC_stack_hint ); str << "You can tune GC_start_size property if you want to (see help gc).\n\r"; out(str); } else { out ("Usage: gc [dump/run/hint]\n\r"); } } void PC::do_invis( const String & arg ) { String str; int invisLevel; if( !(bool)arg ) { if( isInvis() ) { str.sprintf( "You currently invisible at level %d.\n\r", getInvisLevel() ); out( str ); } else out( "You are not affected by any invisibility.\n\r" ); return; } invisLevel = arg.asInt(); if( invisLevel == 0 ) { if( isInvis() ) { out( "You fade into existence.\n\r" ); str.sprintf( "\n\r%s fades into existence.\n\r", (const char*)getName() ); in_room->outAllCharExcept( str, this, 0 ); } } else { if( !isInvis() ) { out( "You fade out of existence.\n\r" ); str.sprintf( "\n\r%s fades out of existence.\n\r", (const char *)getName() ); in_room->outAllCharExcept( str, this, 0 ); } } setInvisLevel( invisLevel ); } void PC::do_goto( const String & arg ) { String str; Char *ch; Room *to; // Search players first, then NPCs if( !( ch = getPCWorld( arg ) ) ) ch = getNPCWorld( arg ); if( ch && ch->inRoom() ) to = ch->inRoom(); else { // Now try rooms in this area unless scope: was specified Index x( arg ); if( !(bool)x.getScope() ) x.setScope( in_room->getArea()->getKey() ); if( !( to = lookupRoom( x ) ) ) { // Now try global (no scope) x.setScope( "" ); to = lookupRoom( x ); } } if( !to ) { out("No such location.\n\r"); return; } if( to == in_room ) return; str << "\n\r" << name << " disappears in a puff of smoke.\n\r"; in_room->outAllCharExcept( str, this, 0 ); // We can use simple out() since character not in room yet. in_room->rmCharInv( this ); str.clr(); str << "\n\r" << name << " appears with an ear-splitting BANG!!\n\r"; to->out( str ); to->addCharInv( this ); setOrientation(0); // just testing, so goto can clear dis-orientation do_look( "" ); } void PC::do_transfer( const String & arg ) { Room *src; Room *dest = in_room; Char *ch = getPCWorld( arg ); if( !ch ) { ch = getNPCWorld( arg ); if( !ch ) { out( "No such character, Coolio.\n\r" ); return; } } if( !( src = ch->inRoom() ) ) { out( "PC::do_transfer() : victim not in a room." ); return; } src->outAllCharExcept( ch->getShort(), ch, 0 ); src->outAllCharExcept( " dissappears in a mushroom cloud.\n\r", ch, 0 ); ch->inRoom()->rmCharInv( ch ); ch->out( shortdesc ); ch->out( " has transferred you!\n\r" ); dest->outAllCharExcept( ch->getShort(), ch, 0 ); dest->outAllCharExcept( " arrives from a puff of smoke.\n\r", ch, 0 ); dest->addCharInv( ch ); if( ch->isPC() ) ((PC *)ch)->do_look( "" ); } void PC::do_slay( const String & arg ) { Char *tch; if( !(bool)arg ) { out( "\n\rWho shall we be slaying?\n\r" ); return; } Char *ch = in_room->getChar( arg ); if( !ch ) { out( "\n\rHmm, you must need your eyes checked.\n\r" ); return; } if( ch == this ) { out( "\n\rAren't we funny today?\n\r" ); return; } for_each( in_room->chars, tch ) if( tch->getFighting() == ch ) tch->stopFighting(); if ( !ch->die( this ) ) return; String str; ch->out( "\n\n\r** YOU HAVE BEEN SLAIN!!! **\n\r" ); out( "\n\rAAAAAHG - Blood everywhere!!!\n\r" ); str << "\n\n\r" << name << " chops " << ch->getShort() << " to pieces!!!\n\r*SPLATTER*\n\r"; in_room->outAllCharExcept( str, this, ch ); if( ch->isNPC() ) { ch->extract(); ch->fordelete(); return; } //INCOMPLETE ch->inRoom()->rmCharInv( ch ); ((PC*)ch)->setState( STATE_MAIN_MENU ); } void PC::do_purge( const String & ) { Char *ch; Object *obj; in_room->chars.reset(); ch = in_room->chars.peek(); for( ; ch; ) { if( ch->isNPC() ) { out( "Purging " ); out( ch->getShort() ); out( ".\n\r" ); ch->extract(); ch->fordelete(); ch = in_room->chars.peek(); continue; } // else in_room->chars.next(); ch = in_room->chars.peek(); } in_room->inv.reset(); while( ( obj = in_room->inv.remove() ) ) { out( "Purging " ); out( obj->getShort() ); out( ".\n\r" ); obj->extract(); obj->fordelete(); } } void PC::do_ostat( const String & arg ) { Object * obj; String str; if( !(bool)arg ) { out( "Stat what?\n\r" ); return; } if( !( obj = inRoom()->getObj( arg ) ) && !( obj = getObjWorld( arg ) ) ) { out( "Didn't find any " ); #ifndef _MSC_VER out( arg + ".\n\r" ); #else out( arg + ( const char *) &(".\n\r") ); #endif /* _MSC_VER */ return; } /* str.sprintf( "Keywords: %s\n\rShort: %s\n\rLong: %s\n\r", obj->getName().chars(), obj->getShort().chars(), obj->getLong().chars() ); */ obj->describeItself( str ); if( obj->inObj() ) str.sprintfAdd( "Inside: %s\n\r", obj->inObj()->getShort().chars() ); else if( obj->inChar() ) str.sprintfAdd( "Carried by: %s\n\r", obj->inChar()->getShort().chars() ); else if( obj->inRoom() ) str.sprintfAdd( "Location: %s\n\r", obj->inRoom()->getName().chars() ); else str += "Object is NOWHERE!!\n\r"; /* OutputBuffer ob(1000); obj->writeTo(ob); str << ob.getDataAsString(); */ out( str ); } void PC::do_mstat( const String & arg ) { Char * ch; String str; if( !(bool)arg ) { out( "Stat whom?\n\r" ); return; } if( !( ch = inRoom()->getNPC( arg ) ) && !( ch = getNPCWorld( arg ) ) ) { out( "Didn't find any " ); #ifndef _MSC_VER out( arg + ".\n\r" ); #else out( arg + ( const char * ) &(".\n\r") ); #endif /* _MSC_VER */ return; } /* str.sprintf( "Keywords: %s\n\rShort: %s\n\rLong: %s\n\r", ch->getName().chars(), ch->getShort().chars(), ch->getLong().chars() ); */ ch->describeItself( str ); str.sprintfAdd( "Location: %s\n\rHp: %d\n\r", ch->inRoom()->getName().chars(), ch->getHP() ); out( str ); } void PC::do_rstat( const String & arg ) { String str; if ( arg ) { out("Sorry, rstat works only for current room for now"); return; } inRoom()->describeItself( str ); out (str); } void PC::do_mwhere( const String & arg ) { String str( 4096 ); NPC * pNPC; if( !(bool)arg ) { out( "Look for what?\n\r" ); return; } for_each( npcs, pNPC ) { if( pNPC->isName( arg ) ) str.sprintfAdd( "%s at location: %s\n\r", pNPC->getShort().chars(), pNPC->inRoom()->getName().chars() ); } out( str ); } void PC::do_page( const String & ) { } void PC::do_reboot( const String & arg ) { void loadSocials(); void loadHelps(); void loadTitle(); String str; if( !(bool)arg ) { out( "Usage: reboot <option>\n\n\r" ); out( "Options are: server world helps socials programs title\n\r" ); return; } if( arg == "server" ) { DOWN = 1; REBOOT = 1; str << "\n\rRebooted by " << name << "\n\n\r"; out( str ); } else if( arg == "socials" ) { Social * social; int ihash; for( ihash = 0; ihash < 26; ihash++ ) { social_table[ihash].reset(); while( ( social = social_table[ihash].remove() ) ) delete social; } loadSocials(); out( "Socials reloaded from database.\n\r" ); } else if( arg == "title" ) { loadTitle(); out( "Title screen reloaded.\n\r" ); } } void PC::do_shutdown( const String & ) { String str; DOWN = 1; str << "\n\rShutdown by " << name << "\n\n\r"; out( str ); } void PC::do_rfind( const String & arg ) { bool global = false; // bool wildcard = false; String str( BUF * 2 ); const Room * ptr; Area *area = in_room->getArea(); // Sorry to mess your code, Fusion, but '*' seems to more in convention // than "all" - Artur if( arg == "*" ) { global = true; for_each( areas, area ) { str << "\n\r--:" << area->getName() << ":--\n\r"; for_each( area->roomIndex, ptr ) { str.sprintfAdd( "%-30s%-40s\n\r", ptr->getKey().chars(), ptr->getName().chars() ); } } } else if ( arg ) { area = lookupArea( arg ); if ( !area ) { str << "Unknown area " << arg << endl; out( str ); return; } str << "Rooms in area " << arg << ":" << endl; str << "-----------------------\n\r"; for_each( area->roomIndex, ptr ) { str.sprintfAdd( "%-30s%-40s\n\r", ptr->getKey().chars(), ptr->getName().chars() ); } } else { str << "Rooms in this area:\n\r-----------------------\n\r"; for_each( area->roomIndex, ptr ) { str.sprintfAdd( "%-30s%-40s\n\r", ptr->getKey().chars(), ptr->getName().chars() ); } } out( str ); } void PC::do_ofind( const String & arg ) { String str( BUF * 2 ); String strName; String strArea; const Object * ptr; Area *area; bool wildcard = false; bool global = false; if( !(bool)arg ) { out( "Find what?\n\r" ); return; } // Use index object to parse arg Index tempIndex( arg ); strName = tempIndex.getKey(); strArea = tempIndex.getScope(); HashTable<Object> *objHashTable; if( strArea == "*" ) global = true; if( strName == "*" ) wildcard = true; str << "Looking up [" << strName << "]\n\r-------------\n\r"; if( !global ) { if( !(bool)strArea ) objHashTable = &in_room->getArea()->objIndex; else { if( !( area = lookupArea( strArea ) ) ) { str << "Unknown area " << strArea << "\n\r"; out( str ); return; } objHashTable = &area->objIndex; } for_each( (*objHashTable), ptr ) { if( !wildcard && !ptr->isName( strName ) ) { objHashTable->next(); continue; } str.sprintfAdd( "%-30s%-40s\n\r", objHashTable->getKey().chars(), ptr->getShort().chars() ); } } else { for_each( areas, area ) { objHashTable = &area->objIndex; for_each( (*objHashTable), ptr ) { if( !wildcard && !ptr->isName( strName ) ) continue; str.sprintfAdd( "%17s:%-30s%-31s\n\r", area->getKey().chars(), objHashTable->getKey().chars(), ptr->getShort().chars() ); } } } out( str ); } void PC::do_owhere( const String & arg ) { Object *obj; String str( BUF ); if( !(bool)arg ) return; for_each( objects, obj ) { if( !obj->isName( arg ) ) continue; else if( obj->inRoom() ) str.sprintfAdd( "%-20s in room %20s\n", obj->getShort().chars(), obj->inRoom()->getName().chars() ); else if( obj->inChar() ) str.sprintfAdd( "%-20s carried by %20s\n", obj->getShort().chars(), obj->inChar()->getShort().chars() ); else if( obj->inObj() ) str.sprintfAdd( "%-20s inside %20s\n", obj->getShort().chars(), obj->inObj()->getShort().chars() ); else str.sprintfAdd( "%-20s is just sort of floating around! BUG!\n", obj->getShort().chars() ); } if( !(bool)str ) str.sprintf( "Could not find any %s.\n\r", arg.chars() ); out( str ); } void PC::do_mfind( const String & arg ) { String str( BUF * 2 ); String strName; String strArea; const NPC *ptr; Area *area; bool global = false; bool wildcard = false; if( !(bool)arg ) { out( "Find what?\n\r" ); return; } HashTable<NPC> *npcHashTable; // Use index constructor to parse the string Index tempIndex( arg ); strArea = tempIndex.getScope(); strName = tempIndex.getKey(); if( strArea == "*" ) global = true; if( strName == "*" ) wildcard = true; str << "Looking up [" << strName << "]\n\r-------------\n\r"; if( !global ) { if( !(bool)strArea ) npcHashTable = &in_room->getArea()->npcIndex; else { if( !( area = lookupArea( strArea ) ) ) { str << "Unknown area " << strArea << "\n\r"; out( str ); return; } npcHashTable = &area->npcIndex; } for_each( (*npcHashTable), ptr ) { if( !wildcard && !ptr->isName( strName ) ) { npcHashTable->next(); continue; } str.sprintfAdd( "%-30s%-40s\n\r", npcHashTable->getKey().chars(), ptr->getShort().chars() ); } } else { for_each( areas, area ) { npcHashTable = &area->npcIndex; for_each( (*npcHashTable), ptr ) { if( !wildcard && !ptr->isName( strName ) ) continue; str.sprintfAdd( "%17s:%-25s%-31s\n\r", area->getKey().chars(), npcHashTable->getKey().chars(), ptr->getShort().chars() ); } } } out( str ); } void PC::do_cset( const String & ) { } void PC::do_grant( const String & arg ) { PC *ch; String person; String privilege; int bit; arg.startArgs(); privilege = arg.getArg(); person = arg.getArg(); if( !(bool)person || !(bool)privilege ) { out( "grant <privilege> <person>\n\r" ); out( "Available privs:\n\r" ); for( bit = 1; ; bit++ ) { if( priv_bit_list[bit].val ) { out( " " ); out( getPrivBitName( bit ) ); if( ! ( bit % 4 ) ) out( "\n\r" ); } else { out( "\n\r" ); return; } } return; } if( !( ch = getPCWorld( person ) ) ) { out( "Could not find anyone by that name.\n\r" ); return; } if( privilege == "all" ) { // Add your individual privs here, setting mass bits not // good in this case. -Fusion // SUPERUSER and DIRECTOR are better left out. ch->setPrivBit( N_ADMIN ); ch->setPrivBit( N_OPERATOR ); ch->setPrivBit( N_MASTERBUILDER ); ch->setPrivBit( N_BUILDER ); ch->setPrivBit( N_QUESTER ); ch->setPrivBit( N_WIZARD ); ch->out( "You have been granted primary privileges.\n\r" ); out( "Primary privileges granted to " ); #ifndef _MSC_VER out( ch->getName() + ".\n\r" ); #else out( ch->getName() + ( const char * ) &(".\n\r") ); #endif /* _MSC_VER */ ch->save(); } else { bit = getPrivBit( privilege.chars() ); if( !bit ) { out( "No such privilege to grant.\n\r" ); return; } ch->setPrivBit( bit ); out( "Privilege granted to " ); out( ch->getName() ); out( ".\n\r" ); ch->out( "You have been granted '" ); ch->out( getPrivBitName( bit ) ); ch->out( "' privileges.\n\r" ); ch->save(); } } void PC::do_revoke( const String & arg ) { PC *ch; int bit; String privilege; String person; arg.startArgs(); privilege = arg.getArg(); person = arg.getArg(); if( !(bool)person || !(bool)privilege ) { out( "revoke <privilege> <person>\n\r" ); out( "Available privs:\n\r" ); for( bit = 1; ; bit++ ) { if( priv_bit_list[bit].val ) { out( " " ); out( getPrivBitName( bit ) ); if( ! ( bit % 4 ) ) out( "\n\r" ); } else { out( "\n\r" ); return; } } return; } ch = getPCWorld( person ); if( !ch ) { out( "Could not find anyone by that name.\n\r" ); return; } if( privilege == "all" ) { ch->clrPrivBits(); ch->out( "All your privileges have been revoked!\n\r" ); out( "Revoking all privileges from " ); #ifndef _MSC_VER out( ch->getName() + ".\n\r" ); #else out( ch->getName() + (const char *) &(".\n\r") ); #endif /* _MSC_VER */ ch->save(); return; } else { bit = getPrivBit( privilege ); if( !bit ) { out( "No such privilege to revoke.\n\r" ); return; } ch->rmPrivBit( bit ); out( "Privilege revoked from " ); out( ch->getName() ); out( ".\n\r" ); ch->out( "Your '" ); ch->out( getPrivBitName( bit ) ); ch->out( "' privilege has been revoked.\n\r" ); ch->save(); } } void PC::do_privileges( const String & arg ) { PC *pc = this; bool found = false; int bit; int count = 1; if( arg ) pc = getPCWorld( arg ); if( !pc ) { out( "No such person.\n\r" ); return; } out( "Privileges granted to " ); out( pc->getName() ); out( ":\n\r" ); for( bit = 1; ; bit++ ) { if( priv_bit_list[bit].val ) { if( pc->authorized( BIT(bit) ) ) { found = true; out( " " ); out( getPrivBitName( bit ) ); if( ! ( count % 4 ) ) out( "\n\r" ); count++; } } else { out( "\n\r" ); return; } } if( !found ) { out( "None.\n\r" ); return; } } #include "vmachine.h" #include "asmloader.h" void PC::do_vm( const String & args ) { String arg1; String arg2; String arg3; VMachine * vm; if ( !vmachine_enabled) { out("VMachine disabled.\n\r"); return; } args.startArgs(); arg1 = args.getArg(); if ( arg1 == "ftest" ) { // will be disabled soon, as it can crash mud if called for // non ( PC, string) argument function arg2 = args.getArg(); arg3 = args.getArgRest(); int fun = lookup_vmfun_number( arg2.chars() ); if ( fun < 0 ) { out("No such fun."); return; } vm = getFreeVM(); vm->defaultValues(); vm->push_string( arg3 ); vm->push_obj( VMT_PC, this ); vm->run(fun); return; } else if ( arg1 == "info" ) { arg2 << "Sizeof VM is " << (int) sizeof (VMachine) << endl; arg2 << "Sizeof String is " << (int) sizeof (String) << endl; arg2 << "Sizeof vmfun is " << (int) sizeof (vmfun) << endl; arg2 << "There are:" << endl; arg2 << vmfun_table.length() << " vmfunctions" << endl; arg2 << vmstatvar_table.length() << " static variables" << endl; arg2 << vmconstant_table.length() << " constants" << endl; VMstatistic( arg2 ); out( arg2 ); return; } else { out ( "Usage:\n\r\tvm ftest name_of_fun\n\r\tvm info\n\r"); return; } } void PC::do_proset( const String & args ) { Property * prop; String arg1; String arg2; const char * txt; args.startArgs(); arg1 = args.getArg(); if ( !(prop = properties.lookup(arg1) ) ) { out("No such property."); return; } arg2 = args.getArgRest(); txt = prop->parseValue(arg2); if ( !txt ) { out("You managed to change this value\n\rRemeber to save changes.\n\r"); return; } out("You failed to change this value because:\n\r"); out(txt); return; } void PC::do_prodisplay( const String & args ) { Property * prop; String str; int nprop = 0; if ( !args ) { for_each( properties, prop ) { str.sprintfAdd("%c %-6.6s %-25.25s %-40.40s\n\r", (prop->getRuntime() ? 'T' : 'R'), prop->getTypeName(), prop->getName().chars(), prop->asText()); nprop++; } str << "Displayed " << nprop << " properties.\n\r"; out(str); return; } prop = properties.lookup(args); if ( !prop ) { out("No such property"); return; } str << "Name: " << prop->getName() << endl; str << "R/T Type: " << (prop->getRuntime() ? "runTime" : "Reboot" )<< endl; str << "Type: " << prop->getTypeName() << endl; str << "Value: " << prop->asText() << endl; str << "Description: " << endl; out(str); str.clr(); str << "../help/propert/" << prop->getName(); view(str.chars()); } #define DEF_PRO_BACKUP "../etc/backup.pro" void PC::do_prosave( const String & args ) { if ( args ) { if ( !args.legalFilename() ) { out("Wrong filename specified\n\r"); return; } String str; str << "../etc/" << args << ".pro"; OutputFile of( str.chars() ); saveProperties(of); out("Properties saved to file ...\n\r"); return; } unlink(DEF_PRO_BACKUP); rename(DEFAULT_PROPERTIES_FILE, DEF_PRO_BACKUP); OutputFile of( DEFAULT_PROPERTIES_FILE ); saveProperties(of); out("Created backup and saved new properties as default.\n\r"); } void PC::do_proload( const String & args ) { String str; if ( args ) { if ( !args.legalFilename() ) { out("Illegal filename.n\r"); return; } str << "../etc/" << args << ".pro"; InputFile inf(str); if ( !inf ) { out("No such file (remember to omit .pro suffix).\n\r"); return; } str.clr(); loadProperties( inf, str ); } else { InputFile inf(DEFAULT_PROPERTIES_FILE); if ( !inf ) { out("No default properties file.\n\r"); return; } loadProperties( inf, str ); } out ( "Properties loaded with following info:\n\r"); out( str ); return; } void PC::do_probackup( const String & args ) { String str; if ( !args.legalFilename() ) { out("Illegal filename\n\r"); return; } InputFile inf( DEFAULT_PROPERTIES_FILE ); if ( !inf ) { out("No default properties file (mudpp.pro) to backup\n\r"); return; } if ( args ) str << "../etc/" << args << ".pro"; else str << DEF_PRO_BACKUP; OutputFile outf( str.chars() ); outf.largewrite( inf.getBuf(), inf.size() ); out("Backup sucessful.\n\r"); } void PC::do_prorestore( const String & args ) { String str; if ( !args.legalFilename() ) { out("Illegal filename"); return; } if ( args ) str << "../etc/" << args << ".pro"; else str << DEF_PRO_BACKUP; InputFile inf(str); if ( !inf ) { out("No such property file"); return; } OutputFile outf( DEFAULT_PROPERTIES_FILE ); outf.largewrite( inf.getBuf(), inf.size() ); out("Restore sucessful.\n\r"); }