/////////////////////////////////////////////////////////// ///////////////// Have an itch? Scratch it! /////////////// ///////////////////////// SCRATCH ///////////////////////// ///////////////////// A MUD Server //////////////////// ///////////////////// By: Jared Devall //////////////////// ///////////////////// Thanks: //////////////////// ///////////////////// DIKU/Merc/ROM //////////////////// ///////////////////// Aetas/Deus Gang //////////////////// ///////////////////// Beej //////////////////// /////////////////////////////////////////////////////////// #include <list> #include "smysql.h" #include "commands.h" #include "commandTable.h" #include "avatar.h" #include "world.h" #include "handler.h" #include "editHandlers.h" #include "stringutil.h" #include "split.h" #include "timestamp.h" // Player commands using namespace std; // Say CmdSay::CmdSay( ) { SetName( "say" ); SetShortcut( "'" ); SetGroup( "player" ); SetEnabled( true ); } bool CmdSay::Execute( Avatar * avatar, const string &args ) { string args1; string buf; if ( args.empty() ) return true; if ( args.length() > 500 ) { args1.append( args, 0, 500 ); } else { args1 = args; } buf << "<" << avatar->Get( "name" ) << "> " << args1 << "{x\n\r"; World::Instance().Broadcast( buf, WCONNECTED ); return true; } // Who: Displays players online CmdWho::CmdWho( ) { SetName( "who" ); SetGroup( "player" ); SetEnabled( true ); } bool CmdWho::Execute( Avatar * avatar, const string &args ) { string buf,countt; int count = 0; list< Avatar *>::iterator a_it; for ( a_it = World::Instance()._avatarList.begin(); a_it != World::Instance()._avatarList.end(); ++a_it, count++ ) { if ( (*a_it)->GetStatus() != CONNECTED ) continue; buf << "> " << (*a_it)->Get( "name" ) << (*a_it)->Get( "title" ) << "{x\n\r"; } countt << count; if ( count > 1 ) buf.insert( 0, "-- " + countt + " Players --\n\r" ); else buf.insert( 0, "-- " + countt + " Player --\n\r" ); avatar->Send( buf ); return true; } // Quit CmdQuit::CmdQuit( ) { SetName( "quit" ); SetGroup( "player" ); SetEnabled( true ); } bool CmdQuit::Execute( Avatar * avatar, const string &args ) { string buf; buf << "## " << avatar->Get( "name" ) << " has disconnected.\n\r"; World::Instance().Broadcast( buf, WCONNECTED ); avatar->SetDisconnected( true ); return true; } // Save CmdSave::CmdSave( ) { SetName( "save" ); SetGroup( "player" ); SetEnabled( true ); } bool CmdSave::Execute( Avatar * avatar, const string &args ) { avatar->Save( ); avatar->Send( "You have been saved.\n\r" ); return true; } // Emote CmdEmote::CmdEmote( ) { SetName( "emote" ); SetShortcut( "." ); SetGroup( "player" ); SetEnabled( true ); } bool CmdEmote::Execute( Avatar * avatar, const string &args ) { string buf; char buf2[MAX_BUFFER]; if ( args.empty() ) { avatar->Send( "What do you wish to emote?\n\r" ); return true; } if ( args[0] != ',' && args[0] != '\'' ) { buf2[0] = ' '; strcpy( buf2+1, args.c_str() ); } else { strcpy( buf2, args.c_str() ); } buf << avatar->Get( "name" ) << buf2 << "\n\r"; World::Instance().Broadcast( buf, WCONNECTED ); return true; } // title CmdTitle::CmdTitle( ) { SetName( "title" ); SetGroup( "player" ); SetEnabled( true ); } bool CmdTitle::Execute( Avatar * avatar, const string &args ) { avatar->Set( "title", args ); avatar->Send( "Title set.\n\r" ); return true; } // prompt CmdPrompt::CmdPrompt( ) { SetName( "prompt" ); SetGroup( "player" ); SetEnabled( true ); } bool CmdPrompt::Execute( Avatar * avatar, const string &args ) { string buf; if ( args.empty() ) { buf << "Syntax: prompt <newprompt>\n\r{WCurrent Prompt: " << avatar->Get( "prompt" ) << "{x\n\r"; avatar->Send( buf ); return true; } for ( string::const_iterator cChar = args.begin(); cChar != args.end(); ++cChar ) { if ( (*cChar) == '%' ) { ++cChar; switch ( (*cChar) ) { case 'R': case 'T': case 's': case 'c': case '%': break; default: buf << "Invalid escape code: " << (*cChar) << "\n\r"; avatar->Send( buf ); return true; } } } buf = args; avatar->Set( "prompt", buf ); avatar->Save(); return true; } // commands CmdCommands::CmdCommands( ) { SetName( "commands" ); SetGroup( "player" ); SetEnabled( true ); } bool CmdCommands::Execute( Avatar * avatar, const string &args ) { list< Command *>::iterator it; int f = 0; avatar->Send( "\t\t-- Commands -- \n\r" ); for ( it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); ++it ) { if ( ( avatar->Get( "group" ).find( (*it)->_group ) != string::npos ) && ( (*it)->_enabled == true ) ) { if ( f == 0 ) { avatar->Send( " %-11s", (*it)->_name.c_str() ); } else { avatar->Send( "%-11s", (*it)->_name.c_str() ); } f++; if ( f == 5 ) { avatar->Send( "\n\r" ); f = 0; } } } avatar->Send( "{x\n\r" ); return true; } // Delete CmdDelete::CmdDelete( ) { SetName( "delete" ); SetGroup( "player" ); SetEnabled( true ); } bool CmdDelete::Execute( Avatar* avatar, const string &args ) { string buf; if ( args.empty() ) { avatar->Send( "Syntax: delete <password>\n\r" ); return true; } if ( avatar->VerifyPassword( args ) ) { buf << "## " << avatar->Get( "name" ) << " has disconnected.\n\r"; World::Instance().Broadcast( buf, WCONNECTED ); avatar->Delete(); avatar->SetDisconnected( true ); } else { avatar->Send( "That password is not correct.\n\r" ); } return true; } // Password CmdPassword::CmdPassword( ) { SetName( "password" ); SetGroup( "player" ); SetEnabled( true ); } bool CmdPassword::Execute( Avatar* avatar, const string &args ) { string buf; string oldPassword; string newPassword; if ( args.empty() ) { avatar->Send( "Syntax: password <oldpassword> <newpassword>\n\r" ); return true; } split( args, oldPassword, newPassword ); if ( avatar->VerifyPassword( oldPassword ) ) { avatar->Set( "password", avatar->EncryptPassword( newPassword ) ); avatar->Send( "Your password has been changed.\n\r" ); } else { avatar->Send( "The old password is incorrect.\n\r" ); } return true; } // Tell CmdTell::CmdTell( ) { SetName( "tell" ); SetGroup( "player" ); SetEnabled( true ); } bool CmdTell::Execute( Avatar* avatar, const string &args ) { string name; string arg; string message; Avatar * target; split( args, name, arg ); if ( ( target = World::Instance().FindAvatar( name ) ) == NULL ) { avatar->Send( "That target cannot be found.\n\r" ); return false; } message << "[From: " << avatar->Get( "name" ) << "] " << arg << "\n\r"; target->Send( message ); target->Set( "reply", avatar->Get( "name" ) ); message.erase(); message << "[To: " << target->Get( "name" ) << "] " << arg << "\n\r"; avatar->Send( message ); return true; } // Reply CmdReply::CmdReply( ) { SetName( "reply" ); SetShortcut( ";" ); SetGroup( "player" ); SetEnabled( true ); } bool CmdReply::Execute( Avatar* avatar, const string &args ) { string name; string message; Avatar * target; if ( ( target = World::Instance().FindAvatar( avatar->Get( "reply" ) ) ) == NULL ) { avatar->Send( "That target cannot be found.\n\r" ); return false; } message << "[From: " << avatar->Get( "name" ) << "] " << args << "\n\r"; target->Send( message ); target->Set( "reply", avatar->Get( "name" ) ); message.erase(); message << "[To: " << target->Get( "name" ) << "] " << args << "\n\r"; avatar->Send( message ); return true; } // ADMIN COMMANDS // Buzz CmdBuzz::CmdBuzz( ) { SetName( "buzz" ); SetGroup( "admin" ); SetEnabled( true ); } bool CmdBuzz::Execute( Avatar * avatar, const string &args ) { string name; string arg; string message; Avatar * target; split( args, name, arg ); if ( ( target = World::Instance().FindAvatar( name ) ) == NULL ) { avatar->Send( "That target cannot be found.\n\r" ); return false; }; message << "\n\r\a{RYou have been buzzed by {W" << avatar->Get( "name" ) << "{R at {W" << Timestamp::Instance().GetDateTime() << "{R.{x\a\n\r"; target->Send( message ); avatar->Send( "Your target has been buzzed!\n\r" ); return true; } CmdEdit::CmdEdit( ) { SetName("edit"); SetGroup("admin"); SetEnabled( true ); } bool CmdEdit::Execute( Avatar * avatar, const string &args ) { if ( !args.empty() ) { avatar->StackHandler( new EditAvatarHandler( avatar, args ) ); } else { avatar->StackHandler( new EditAvatarHandler ); } return true; } // Shutdown CmdShutdown::CmdShutdown( ) { SetName( "shutdown" ); SetGroup( "admin" ); SetEnabled( true ); } bool CmdShutdown::Execute( Avatar* avatar, const string &args ) { string buf; buf << "## Scratch is being shutdown.\n\r"; World::Instance().Broadcast( buf, WCONNECTED ); World::Instance().Die(); return true; } // Copyover CmdReboot::CmdReboot( ) { SetName( "reboot" ); SetGroup( "admin" ); SetEnabled( true ); } bool CmdReboot::Execute( Avatar* avatar, const string &args ) { World::Instance().Copyover(); return true; } // Disable CmdDisable::CmdDisable( ) { SetName( "disable" ); SetGroup( "admin" ); SetEnabled( true ); } bool CmdDisable::Execute( Avatar * avatar, const string &args ) { list< Command *>::iterator it; string command; string query; split( args, command ); if ( args.empty() ) { Mysql::LMAP::iterator command_info; Mysql::RESULT::iterator commands; query << "SELECT * FROM disabled_commands"; if ( !Mysql::Instance().Load( query.c_str() ) ) { avatar->Send( "There are no disabled commands.\n\r" ); return true; } query.erase(); query << " -- Disabled Commands -- \n\r"; for ( commands = Mysql::Instance()._info.begin(); commands != Mysql::Instance()._info.end(); ++commands ) { command_info = (*commands).find( "command" ); query << "[" << command_info->second << " "; command_info = (*commands).find("disabler"); query << command_info->second << "]\n\r"; } avatar->Send( query ); return true; } // Either disable or enable the command; update the database for ( it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); ++it ) { if ( str_cmp( (*it)->_name, command ) ) { if ( (*it)->_enabled == true ) { (*it)->_enabled = false; query << "INSERT INTO disabled_commands SET command='" << (*it)->_name << "', disabler='" << avatar->Get( "name" ) << "' "; if ( !Mysql::Instance().Query( query.c_str() ) ) { return false; } avatar->Send( "Command disabled.\n\r" ); } else { (*it)->_enabled = true; query << "DELETE FROM disabled_commands WHERE command='" << (*it)->_name << "'"; if ( !Mysql::Instance().Query( query.c_str() ) ) { return false; } avatar->Send( "Command enabled.\n\r" ); } return true; } } avatar->Send( "That command does not exist.\n\r" ); return true; } CmdSockets::CmdSockets( ) { SetName("sockets"); SetGroup("admin"); SetEnabled( true ); } bool CmdSockets::Execute( Avatar * avatar, const string &args ) { string buf; list< Avatar * >::iterator it; buf << "\t\t-- Sockets --\n\r"; for ( it = World::Instance()._avatarList.begin(); it != World::Instance()._avatarList.end(); ++it ) { buf << (*it)->Get( "name" ) << ": " << (*it)->GetSocket()->GetSocketIP() << " (descriptor: " << (*it)->GetSocket()->GetDescriptor() << ")\n\r"; } avatar->Send( buf ); return true; } // Disconnect CmdDisconnect::CmdDisconnect( ) { SetName("disconnect"); SetGroup("admin"); SetEnabled( true ); } bool CmdDisconnect::Execute( Avatar * avatar, const string &args ) { string starget; string arguments; Avatar * target; if ( args.empty() ) { avatar->Send( "Syntax: disconnect <player>\n\r" ); return false; } split ( args, starget, arguments ); if ( ( target = World::Instance().FindAvatar( starget ) ) == NULL ) { avatar->Send( "That target cannot be found.\n\r" ); return false; } target->SetDisconnected( true ); avatar->Send( "Your target has been disconnected.\n\r" ); return true; }