/* ....[@@@..[@@@..............[@.................. 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@falcon.mercer.peachnet.edu MUD++ development mailing list mudpp-list@spice.com ------------------------------------------------------------------------------ pc_wiz.cc */ #include "string.h" #include "llist.h" #include "room.h" #include "repop.h" #include "indexable.h" #include "server.h" #include "area.h" #include "bit.h" #include "screen.h" #include "pc.h" #include "global.h" // This is a utility function which I change often just for debuggin // things void PC::do_debug( String & ) { int i; String strOut; char buf[ 4096 ]; char buf2[ 4096 ]; String str( 4096 ); static timeval avg; timeval tin1, tout1, dif1; timeval tin2, tout2, dif2, dif3; strcpy( buf2, "testing dfasdfkjsadhfklasdfhasdlkfsdfkljh" ); gettimeofday( &tin1, 0 ); for( i = 0; i < 100000; i++ ) { strcpy( buf, buf2 ); } gettimeofday( &tout1, 0 ); dif1.tv_sec = tout1.tv_sec - tin1.tv_sec; dif1.tv_usec = tout1.tv_usec - tin1.tv_usec; if( dif1.tv_usec < 0 ) { dif1.tv_sec--; dif1.tv_usec += 1000000; } strOut.sprintf( "char time: secs(%ld) usec(%ld)\n\r", dif1.tv_sec, dif1.tv_usec ); out( strOut ); gettimeofday( &tin2, 0 ); for( i = 0; i < 100000; i++ ) { str = buf2; } gettimeofday( &tout2, 0 ); dif2.tv_sec = tout2.tv_sec - tin2.tv_sec; dif2.tv_usec = tout2.tv_usec - tin2.tv_usec; if( dif2.tv_usec < 0 ) { dif2.tv_sec--; dif2.tv_usec += 1000000; } strOut.sprintf( "Str time: secs(%ld) usec(%ld)\n\r", dif2.tv_sec, dif2.tv_usec ); out( strOut ); dif3.tv_sec = dif2.tv_sec - dif1.tv_sec; dif3.tv_usec = dif2.tv_usec - dif1.tv_usec; if( dif3.tv_usec < 0 ) { dif3.tv_sec--; dif3.tv_usec += 1000000; } strOut.sprintf( "Diff: secs(%ld) usec(%ld)\n\r", dif3.tv_sec, dif3.tv_usec ); out( strOut ); } // Just a test to get ident working. Will do non-blocking when // this is done. void PC::do_ident( String & arg ) { char ip[ 256 ]; char buf[ 256 ]; PC *pc; Socket *socket; if( !( pc = getPCWorld( arg ) ) ) { out( "No such player connected.\n\r" ); return; } strcpy( ip, pc->getSock()->getHostName() ); socket = new Socket( ip, 113 ); if( socket->error() ) { out( "Socket error.\n\r" ); delete socket; return; } if( socket->connect() == -1 ) { out( "Connect error.\n\r" ); delete socket; return; } out( "Connected to ident server on " ); out( socket->getHostName() ); out( "\n\r" ); int foreign_port = pc->getSock()->getPort(); int size = sprintf( buf, "%d , %d\n\r", foreign_port, 4000 ); socket->write( buf, size ); *buf = 0; while( !*buf ) socket->read( buf ); delete socket; out( buf ); } void PC::do_cat( String & arg ) { if( !arg ) return; view( arg.chars() ); } void PC::do_users( String & ) { String str; PC *pc; LList<PC> tlist = pcs; tlist.reset(); str = "Name Host Foreign Port\n\r"; while( ( pc = tlist.peek() ) ) { tlist.next(); str.sprintfAdd( "%13s%20s%-7d\n\r", pc->getName().chars(), pc->getSock()->getHostName(), pc->getSock()->getPort() ); } out( str ); } void PC::do_echo( String & arg ) { String str; str << "\n\n\r" << arg << "\n\r"; outAllCharExcept( str, 0, 0 ); } void PC::do_immtalk( String & arg ) { PC *ch; LList<PC> tlist = pcs; String str; str << BYELLOW << name << " : " << arg << "\n\r" << NTEXT; tlist.reset(); while( ( ch = tlist.peek() ) ) { if( ch != this ) ch->out( "\n\r" ); ch->out( str ); tlist.next(); } } void PC::do_advance ( String & arg ) { if( classnow != CLASS_IMM ) { out("You wish you were this powerful.\n\r"); return; } arg.startArgs(); String argName = arg.getArg(); String argLevel = arg.getArg(); if( !argName || !argLevel ) { out( "Usage: advance <person> <level>\n\r" ); return; } PC *plr = in_room->getPC( argName ); if( !plr ) { out( "No one here by that name.\n\r" ); return; } int lev = argLevel.asInt(); if( lev < 1 ) { out( "No can do.\n\r" ); return; } // Need to check levels here. plr->advance( lev ); } void PC::do_memory( String & ) { out( "\n\r[disabled for now --Fusion]\n\r" ); } void PC::do_invis( String & ) { char buf[ BUF ]; /*if( IsInvisible() ) { out( "You fade into existence.\n\r" ); sprintf( buf, "\n\n\r%s fades into existence.\n\r", name.chars() ); } else { out( "You suddenly vanish.\n\r" ); sprintf( buf, "\n\n\r%s suddenly vanishes into thin air.\n\r", name.chars() ); } */ //TOGGLE_BIT( obj_flags, OBJ_INVISIBLE ); // in_room->outAllCharExcept( buf, this, NULL ); } void PC::do_goto( 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( !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, NULL ); // 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 ); do_look( "" ); } void PC::do_transfer( 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( String & arg ) { if( !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; } // OK - Lets build the corpse Object. // This stuff is so straighforward I don't make a seperate function. String str; Object *corpse = new Object; corpse->setName( "corpse" ); str << "the corpse of " << ch->getShort(); corpse->setShort( str ); str.clr(); str << "The corpse of " << ch->getShort() << " lies here, rotting."; corpse->setLong( str ); corpse->setWeight( ch->getWeight() ); corpse->setType( ITEM_CORPSE ); corpse->setTimer( 2 ); corpse->toWorld(); in_room->addObjInv( corpse ); ch->inRoom()->rmCharInv( ch ); ch->out( "\n\n\r** YOU HAVE BEEN SLAIN!!! **\n\r" ); out( "\n\rAAAAAHG - Blood everywhere!!!\n\r" ); str.clr(); str << "\n\n\r" << name << " chops " << ch->getShort() << " to pieces!!!\n\r*SPLATTER*\n\r"; in_room->outAllCharExcept( str, this, ch ); // Mob corpses are traditional. Transfer the inventory to corpse. if( ch->isNPC() ) { } if( ch->isNPC() ) { ch->fromWorld(); delete ch; return; } //INCOMPLETE ((PC*)ch)->setState( STATE_MAIN_MENU ); } void PC::do_purge( String & ) { Char *ch; Object *obj; in_room->chars.reset(); while( ( ch = in_room->chars.peek() ) ) { if( ch->isNPC() ) { out( "Purging " ); out( ch->getShort() ); out( ".\n\r" ); in_room->rmCharInv( ch ); ch->fromWorld(); delete ch; continue; } in_room->chars.next(); } in_room->inv.reset(); while( ( obj = in_room->inv.remove() ) ) { out( "Purging " ); out( obj->getShort() ); out( ".\n\r" ); obj->fromWorld(); delete obj; } } void PC::do_page( String & ) { } void PC::do_reboot( String & ) { String str; DOWN = 1; REBOOT = 1; str << "\n\rRebooted by " << name << "\n\n\r"; out( str ); } void PC::do_shutdown( String & ) { String str; DOWN = 1; str << "\n\rShutdown by " << name << "\n\n\r"; out( str ); } void PC::do_rfind( String & arg ) { bool global = false; // bool wildcard = false; String str( BUF * 2 ); const Room * ptr; Area *area = in_room->getArea(); if( arg == "all" ) { global = true; areas.reset(); while( ( area = areas.peek() ) ) { areas.next(); str << "\n\r--:" << area->getName() << ":--\n\r"; area->roomIndex.reset(); while( ( ptr = area->roomIndex.peek() ) ) { area->roomIndex.next(); str.sprintfAdd( "%-30s%-40s\n\r", ptr->getKey().chars(), ptr->getName().chars() ); } } } else { str << "Rooms in this area:\n\r-----------------------\n\r"; area->roomIndex.reset(); while( ( ptr = area->roomIndex.peek() ) ) { area->roomIndex.next(); str.sprintfAdd( "%-30s%-40s\n\r", ptr->getKey().chars(), ptr->getName().chars() ); } } out( str ); } void PC::do_ofind( String & arg ) { String str( BUF * 2 ); String strName; String strArea; bool wildcard = false; const Object * ptr; Area *area; bool global = false; if( !arg ) { out( "Find what?\n\r" ); return; } // Use index object to parse arg Index index( arg ); strName = index.getKey(); strArea = index.getScope(); IndexList<Object> *objIndex; if( strArea && strArea == "*" ) { global = true; } if( strName == "*" ) { wildcard = true; } str << "Looking up [" << strName << "]\n\r-------------\n\r"; if( !global ) { if( !strArea ) objIndex = &in_room->getArea()->objIndex; else { if( !( area = lookupArea( strArea ) ) ) { str << "Unknown area " << strArea << "\n\r"; out( str ); return; } objIndex = &area->objIndex; } objIndex->reset(); while( ( ptr = objIndex->peek() ) ) { index = objIndex->getIndex(); objIndex->next(); if( !wildcard && !ptr->isName( strName ) ) continue; str.sprintfAdd( "%-30s%-40s\n\r", index.getKey().chars(), ptr->getShort().chars() ); } } else { areas.reset(); while( ( area = areas.peek() ) ) { areas.next(); objIndex = &area->objIndex; objIndex->reset(); while( ( ptr = objIndex->peek() ) ) { // Get the index of that object index = objIndex->getIndex(); // Then increment objIndex->next(); if( !wildcard && !ptr->isName( strName ) ) continue; str.sprintfAdd( "%17s:%-30s%-31s\n\r", area->getKey().chars(), index.getKey().chars(), ptr->getShort().chars() ); } } } out( str ); } void PC::do_owhere( String & arg ) { Object *obj; String str( BUF ); if( !arg ) return; objects.reset(); while( ( obj = objects.peek() ) ) { objects.next(); 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( !str ) str.sprintf( "Could not find any %s.\n\r", arg.chars() ); out( str ); } void PC::do_mfind( String & arg ) { String str( BUF * 2 ); String strName; String strArea; char arg1[ 256 ]; const NPC *ptr; Area *area; bool global = false; bool wildcard = false; if( !arg ) { out( "Find what?\n\r" ); return; } IndexList<NPC> *npcIndex; // Use index constructor to parse the string Index index( arg ); strArea = index.getScope(); strName = index.getKey(); if( strArea && strArea == "*" ) { global = true; } if( strName == "*" ) { wildcard = true; } str << "Looking up [" << strName << "]\n\r-------------\n\r"; if( !global ) { if( !strArea ) npcIndex = &in_room->getArea()->npcIndex; else { if( !( area = lookupArea( strArea ) ) ) { str << "Unknown area " << strArea << "\n\r"; out( str ); return; } npcIndex = &area->npcIndex; } npcIndex->reset(); while( ( ptr = npcIndex->peek() ) ) { // Get index for that npc index = npcIndex->getIndex(); // Increment npcIndex->next(); if( !wildcard && !ptr->isName( strName ) ) continue; str.sprintfAdd( "%-30s%-40s\n\r", index.getKey().chars(), ptr->getShort().chars() ); } } else { areas.reset(); while( ( area = areas.peek() ) ) { areas.next(); npcIndex = &area->npcIndex; npcIndex->reset(); while( ( ptr = npcIndex->peek() ) ) { // Get index of npc index = npcIndex->getIndex(); // Then increment npcIndex->next(); if( !wildcard && !ptr->isName( strName ) ) continue; str.sprintfAdd( "%17s:%-25s%-31s\n\r", area->getKey().chars(), index.getKey().chars(), ptr->getShort().chars() ); } } } out( str ); } void PC::do_cset( String & arg ) { } void PC::do_grant( String & arg ) { PC *ch; String person; String privilege; int bit; arg.startArgs(); privilege = arg.getArg(); person = arg.getArg(); if( !person || !privilege ) { out( "grant <privilege> <person>\n\r" ); return; } ch = getPCWorld( person ); if( !ch ) { out( "Could not find anyone by that name.\n\r" ); return; } if( privilege == "all" ) { } else { bit = getPrivBit( privilege.chars() ); if( bit == NULLBIT ) { out( "No such privilege to grant.\n\r" ); return; } ch->setPrivBit( bit ); out( "Privilege granted to " ); out( ch->getName() ); out( ".\n\r" ); } } void PC::do_revoke( String & arg ) { PC *ch; int bit; String privilege; String person; arg.startArgs(); privilege = arg.getArg(); person = arg.getArg(); if( !person || !privilege ) { out( "revoke <privilege> <person>\n\r" ); return; } ch = getPCWorld( person ); if( !ch ) { out( "Could not find anyone by that name.\n\r" ); return; } if( privilege == "all" ) { } else { bit = getPrivBit( privilege.chars() ); if( bit == NULLBIT ) { out( "No such privilege to revoke.\n\r" ); return; } ch->rmPrivBit( bit ); out( "Privilege revoked from " ); out( ch->getName() ); out( ".\n\r" ); } }