/*
....[@@@..[@@@..............[@.................. 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");
}