///////////////////////////////////////////////////////////
///////////////// 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"
#include "log.h"
#include "room.h"

// Player commands

using namespace std;

//movement
CmdWest::CmdWest()
{
    SetName( "west" );
    SetGroup( "player" );
    SetEnabled( true );
}

bool CmdWest::Execute( Char* avatar, const string &args )
{
  Room *r = NULL;
  Room *prev = NULL;
  string s;

  if ( !avatar->_room )
   return false;

  r = (avatar->_room->GetExit("west"));
  prev = avatar->_room;

  //no exit?
  if ( r == NULL && ((r = avatar->_room->GetExit("w")) == NULL ))
  {
    avatar->Send( "There is no exit in that direction!\n\r");
    return false;
  }

  avatar->Send( "You leave to the west.\n\r");

  // show arrival
  s << avatar->Get("name") << " arrives from the east.\n\r";
  r->Broadcast(s);

  // now set and change rooms
  r->InsertAvatar( avatar );

  // show leaving message
  s = "";
  s << avatar->Get("name") << " leaves to the west.\n\r";
  prev->Broadcast(s);
  return true;
}

CmdEast::CmdEast()
{
    SetName( "east" );
    SetGroup( "player" );
    SetEnabled( true );
}

bool CmdEast::Execute( Char* avatar, const string &args )
{
  Room *r = NULL;
  Room *prev = NULL;
  string s;

  if ( !avatar->_room )
   return false;

  r = avatar->_room->GetExit("east");
  prev = avatar->_room;

  //no exit?
  if ( r == NULL && ((r = avatar->_room->GetExit("e")) == NULL ))
  {
    avatar->Send( "There is no exit in that direction!\n\r");
    return false;
  }

  avatar->Send( "You leave to the east.\n\r");

  // show arrival
  s << avatar->Get("name") << " arrives from the west.\n\r";
  r->Broadcast(s);

  // now set and change rooms
  r->InsertAvatar( avatar );

  // show leaving message
  s = "";
  s << avatar->Get("name") << " leaves to the east.\n\r";
  prev->Broadcast(s);
  return true;
}

CmdNorth::CmdNorth()
{
    SetName( "north" );
    SetGroup( "player" );
    SetEnabled( true );
}

bool CmdNorth::Execute( Char* avatar, const string &args )
{
  Room *r = NULL;
  Room *prev = NULL;
  string s;

  if ( !avatar->_room )
   return false;

  r = avatar->_room->GetExit("north");
  prev = avatar->_room;

  //no exit?
  if ( r == NULL && (r = avatar->_room->GetExit("n")) == NULL )
  {
    avatar->Send( "There is no exit in that direction!\n\r");
    return false;
  }

  avatar->Send( "You leave to the north.\n\r");

  // show arrival
  s << avatar->Get("name") << " arrives from the south.\n\r";
  r->Broadcast(s);

  // now set and change rooms
  r->InsertAvatar( avatar );

  // show leaving message
  s = "";
  s << avatar->Get("name") << " leaves to the north.\n\r";
  prev->Broadcast(s);
  return true;
}

CmdSouth::CmdSouth()
{
    SetName( "south" );
    SetGroup( "player" );
    SetEnabled( true );
}

bool CmdSouth::Execute( Char* avatar, const string &args )
{
  Room *r = NULL;
  Room *prev = NULL;
  string s;

  if ( !avatar->_room )
   return false;

  r = avatar->_room->GetExit("south");
  prev = avatar->_room;
  
  //no exit?
  if ( r == NULL && ((r = avatar->_room->GetExit("s")) == NULL ))
  {
    avatar->Send( "There is no exit in that direction!\n\r");
    return false;
  }
  
  avatar->Send( "You leave to the south.\n\r");

  // show arrival
  s << avatar->Get("name") << " arrives from the north.\n\r";
  r->Broadcast(s);

  // now set and change rooms
  r->InsertAvatar( avatar );

  // show leaving message
  s = "";
  s << avatar->Get("name") << " leaves to the south.\n\r";
  prev->Broadcast(s);
  return true;
}

CmdNorthEast::CmdNorthEast()
{
    SetName( "northeast" );
    SetGroup( "player" );
    SetEnabled( true );
}

bool CmdNorthEast::Execute( Char* avatar, const string &args )
{
  Room *r = NULL;
  Room *prev = NULL;
  string s;

  if ( !avatar->_room )
   return false;

  r = avatar->_room->GetExit("northeast");
  prev = avatar->_room;

  //no exit?
  if ( r == NULL && ((r = avatar->_room->GetExit("ne")) == NULL ))
  {
    avatar->Send( "There is no exit in that direction!\n\r");
    return false;
  }

  avatar->Send( "You leave to the northeast.\n\r");

  // show arrival
  s << avatar->Get("name") << " arrives from the southwest.\n\r";
  r->Broadcast(s);

  // now set and change rooms
  r->InsertAvatar( avatar );

  // show leaving message
  s = "";
  s << avatar->Get("name") << " leaves to the northeast.\n\r";
  prev->Broadcast(s);
  return true;
}

CmdNorthWest::CmdNorthWest()
{
    SetName( "northwest" );
    SetGroup( "player" );
    SetEnabled( true );
}

bool CmdNorthWest::Execute( Char* avatar, const string &args )
{
  Room *r = NULL;
  Room *prev = NULL;
  string s;

  if ( !avatar->_room )
   return false;

  r = avatar->_room->GetExit("northwest");
  prev = avatar->_room;

  //no exit?
  if ( r == NULL && ((r = avatar->_room->GetExit("nw")) == NULL ) )
  {
    avatar->Send( "There is no exit in that direction!\n\r");
    return false;
  }

  avatar->Send( "You leave to the northwest.\n\r");

  // show arrival
  s << avatar->Get("name") << " arrives from the southeast.\n\r";
  r->Broadcast(s);

  // now set and change rooms
  r->InsertAvatar( avatar );

  // show leaving message
  s = "";
  s << avatar->Get("name") << " leaves to the northwest.\n\r";
  prev->Broadcast(s);
  return true;
}

CmdSouthEast::CmdSouthEast()
{
    SetName( "southeast" );
    SetGroup( "player" );
    SetEnabled( true );
}

bool CmdSouthEast::Execute( Char* avatar, const string &args )
{
  Room *r = NULL;
  Room *prev = NULL;
  string s;

  if ( !avatar->_room )
   return false;

  r = avatar->_room->GetExit("southeast");
  prev = avatar->_room;

  //no exit?
  if ( r == NULL && ((r = avatar->_room->GetExit("se")) == NULL ) )
  {
    avatar->Send( "There is no exit in that direction!\n\r");
    return false;
  }

  avatar->Send( "You leave to the southeast.\n\r");

  // show arrival
  s << avatar->Get("name") << " arrives from the northwest.\n\r";
  r->Broadcast(s);

  // now set and change rooms
  r->InsertAvatar( avatar );

  // show leaving message
  s = "";
  s << avatar->Get("name") << " leaves to the southeast.\n\r";
  prev->Broadcast(s);
  return true;
}

CmdSouthWest::CmdSouthWest()
{
    SetName( "southwest" );
    SetGroup( "player" );
    SetEnabled( true );
}

bool CmdSouthWest::Execute( Char* avatar, const string &args )
{
  Room *r = NULL;
  Room *prev = NULL;
  string s;

  if ( !avatar->_room )
   return false;

  r = avatar->_room->GetExit("southwest");
  prev = avatar->_room;

  //no exit?
  if ( r == NULL && ((r = avatar->_room->GetExit("sw")) == NULL ))
  {
    avatar->Send( "There is no exit in that direction!\n\r");
    return false;
  }

  avatar->Send( "You leave to the southwest.\n\r");

  // show arrival
  s << avatar->Get("name") << " arrives from the northeast.\n\r";
  r->Broadcast(s);

  // now set and change rooms
  r->InsertAvatar( avatar );

  // show leaving message
  s = "";
  s << avatar->Get("name") << " leaves to the southwest.\n\r";
  prev->Broadcast(s);
  return true;
}

//Help
CmdHelp::CmdHelp()
{
  SetName( "help" );
  SetGroup( "player" );
  SetEnabled( true );
}

bool CmdHelp::Execute( Char* avatar, const string &args )
{
  Help* help = NULL;
  string s;
  
  if ( args.empty() )
  {
    // show default comprehensive help
    return true;
  }
  
  // perform the search and check perms
  if ( ((help = World::Instance().FindHelp(args)) == NULL) ||
       (avatar->Get("group").find( help->Get("perm") ) == string::npos))
  {
     // perform similar lookups here
     s << "\n\rNo help file with name '" << args << "' was found.\n\r";
     avatar->Send(s);
     
     return false;
  }
  
  //display help file
  s << "\n\r~-~-~-( " << help->Get("name") << " )~-~-~-\n\r";
  s << help->Get("text");
  s << "\n\r\n\r";
  s << "--------------------\n\r";
  s << "Author:       " << help->Get("author") << "\n\r";
  s << "Created:      " << help->Get("creation_date") << "\n\r";
  s << "Last Updated: " << help->Get("last_update") << "\n\r\n\r";
  
  avatar->Send(s);
  
  return true;
}

//Look
CmdLook::CmdLook()
{
  SetName( "look" );
  SetGroup("player");
  SetEnabled( true );
}

bool CmdLook::Execute( Char* avatar, const string &args )
{
  string s, title;
  RoomMap rmap;
  
  if ( !avatar )
   return false;
  else if ( !avatar->_room ) // need non-null avatar to check room
   return false;

  rmap = avatar->_room->GetExits();

  //display the room's name, desc, and exits
  s << "\n\r~-~-~-( " << avatar->_room->Get("name") << " )~-~-~-\n\r";
  s << avatar->_room->Get("description") << "\n\r\n\r";
  
  
  s << "\n\r\n\r{c";
  
  // show players
  for ( list<Char*>::const_iterator x = avatar->_room->_charList.begin(); x != avatar->_room->_charList.end(); x++ )
  {
   if ( (*x) == avatar )
    continue;
    
   s << (*x)->Get("name");

   // if there is a title
   if ( !(title = (*x)->Get("title")).empty() )
     s << "," << title << "\n\r";
  }
  
  s << "\n\r{WExits: ";
  
  // loop through exits and display the name
  for ( RoomMap::const_iterator i = rmap.begin(); i != rmap.end(); i++ )
   s << " " << i->first;
   
  s << "\n\r\n\r";
  
  avatar->Send(s);
  return true;
}

// Say
CmdSay::CmdSay( )
{
	SetName( "say" );
	SetShortcut( "'" );
	SetGroup( "player" );
	SetEnabled( true );
}

bool CmdSay::Execute( Char * 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";
	
	avatar->_room->Broadcast( buf );
	return true;
}

// Who: Displays players online
CmdWho::CmdWho( )
{
	SetName( "who" );
	SetGroup( "player" );
	SetEnabled( true );
}

bool CmdWho::Execute( Char * avatar, const string &args ) {
	string buf,countt, title;
	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" );

        if ( !(title = (*a_it)->Get( "title" )).empty())
         buf << "," << title;

        buf << "{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( Char * 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( Char * 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( Char * 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( Char * 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( Char * 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 );
}

// Edit: 1/17/06 - modified to show all commands in groups instead of a blob
bool CmdCommands::Execute( Char * avatar, const string &args )
{
    string group = avatar->Get("group");
	list< Command *>::iterator it;	
	int f = 0;
	
	avatar->Send( "\t\t-- Commands -- \n\r" );
	
	if ( group.length() > 6 ) // players are length 6
     avatar->Send( "\n\rPlayer Commands:\n\r");

	for ( it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); ++it )
    {
		if (  (*it)->_group == "player" && ( (*it)->_enabled == true ) )
        {
			if ( f == 0 )
			   avatar->Send( "  %-15s", (*it)->_name.c_str() );
            else
			   avatar->Send( "%-15s", (*it)->_name.c_str() );

		    f++;

		    if ( f == 5 )
            {
			   avatar->Send( "\n\r" );
			   f = 0;
			}
		}
	}

    // this check only applies to admins, enforcers, imp's and other immortals
    if ( group.length() > 6 )
    {
//       //admin commands
//       if ( group.find("admin") != string::npos )
//       {
//        avatar->Send( "\n\n\rAdmin Commands:\n\r");
//          f = 0;
//
//    	for ( it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); ++it )
//        {
//    		if (  (*it)->_group == "admin" && ( (*it)->_enabled == true ) )
//            {
//    			if ( f == 0 )
//    			   avatar->Send( "  %-15s", (*it)->_name.c_str() );
//                else
//    			   avatar->Send( "%-15s", (*it)->_name.c_str() );
//
//    		    f++;
//
//    		    if ( f == 5 )
//                {
//    			   avatar->Send( "\n\r" );
//    			   f = 0;
//    			}
//    		}
//    	} // end for
//       }
       
       // enforcer commands
       if ( group.find("enforcer") != string::npos )
       {
        avatar->Send( "\n\n\rEnforcer Commands:\n\r");

        f = 0;

    	for ( it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); ++it )
        {
    		if (  (*it)->_group == "enforcer" && ( (*it)->_enabled == true ) )
            {
    			if ( f == 0 )
    			   avatar->Send( "  %-15s", (*it)->_name.c_str() );
                else
    			   avatar->Send( "%-15s", (*it)->_name.c_str() );

    		    f++;

    		    if ( f == 5 )
                {
    			   avatar->Send( "\n\r" );
    			   f = 0;
    			}
    		}
    	} // end for
       }
       
       // imp commands
       if ( group.find("imp") != string::npos )
       {
        avatar->Send( "\n\n\rImplementor Commands:\n\r");
        
        f = 0;

    	for ( it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); ++it )
        {
    		if (  (*it)->_group == "imp" && ( (*it)->_enabled == true ) )
            {
    			if ( f == 0 )
    			   avatar->Send( "  %-15s", (*it)->_name.c_str() );
                else
    			   avatar->Send( "%-15s", (*it)->_name.c_str() );

    		    f++;

    		    if ( f == 5 )
                {
    			   avatar->Send( "\n\r" );
    			   f = 0;
    			}
    		}
    	} // end for
       }
     } // end if


// the old method
//	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( Char* 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( Char* 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( Char* avatar, const string &args ) {
	string name;
	string arg;
	string message;
	Char * target;
	
	split( args, name, arg );
	if ( ( target = World::Instance().FindChar( 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( Char* avatar, const string &args ) {
	string name;
	string message;
	Char * target;
	
	if ( ( target = World::Instance().FindChar( 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;
}

// Buzz, why was this originally an admin command?
CmdBuzz::CmdBuzz( ) {
	SetName( "buzz" );
	SetGroup( "player" );
	SetEnabled( true );
}

bool CmdBuzz::Execute( Char * avatar, const string &args ) {
		string name;
	string arg;
	string message;
	Char * target;
	
	split( args, name, arg );
	if ( ( target = World::Instance().FindChar( 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;
}

// ADMIN COMMANDS

CmdHedit::CmdHedit()
{
  SetName("hedit");
  SetGroup( "imp" );
  SetEnabled( true );
}

bool CmdHedit::Execute( Char * avatar, const string &args )
{
  if ( !args.empty() )
    avatar->StackHandler( new EditHelpHandler( avatar, args ) );
  else
    avatar->StackHandler( new EditHelpHandler );
    
  return true;
}

CmdRedit::CmdRedit()
{
  SetName("redit");
  SetGroup( "imp" );
  SetEnabled( true );
}

bool CmdRedit::Execute( Char * avatar, const string &args )
{
  if ( !args.empty() )
    avatar->StackHandler( new EditRoomHandler( avatar, args ) );
  else
    avatar->StackHandler( new EditRoomHandler );
    
  return true;
}

CmdEdit::CmdEdit( )
{
	SetName("medit");
	SetGroup("imp");
	SetEnabled( true );
}

bool CmdEdit::Execute( Char * 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( "imp" );
	SetEnabled( true );
}

bool CmdShutdown::Execute( Char* avatar, const string &args )
{
	string buf;
	
	buf << "## Kaladea is being shutdown.\n\r";
	World::Instance().Broadcast( buf, WCONNECTED );
	World::Instance().Die();	
	return true;
}

// Copyover
CmdReboot::CmdReboot( )
{
	SetName( "reboot" );
	SetGroup( "imp" );
	SetEnabled( true );
}

bool CmdReboot::Execute( Char* avatar, const string &args )
{
	World::Instance().Copyover();	
	return true;
}

// Disable
CmdDisable::CmdDisable( )
{
	SetName( "disable" );
	SetGroup( "imp" );
	SetEnabled( true );	
}

bool CmdDisable::Execute( Char * 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("enforcer");
	SetEnabled( true );
}

bool CmdSockets::Execute( Char * 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("enforcer");
	SetEnabled( true );
}

bool CmdDisconnect::Execute( Char * 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;
	}

    // only playes will have length <= 6, and only implementors can boot imms
	if ( ((target->Get("group")).length() > 6) && ((avatar->Get("group")).find("imp") == string::npos ) )
	{
       string s;
       
       s << "IMM ABUSE: " << avatar->Get("name") << " tried to disconnect " << target->Get("name") << ".";

       glog( s.c_str() ); // log it

       avatar->Send( "You cannot do that to fellow staff members!\n\r");
       
       // tell the target whats up
       s = "";
       s << avatar->Get("name") << " tried to disconnect you!\n\r";
       target->Send( s );
       
       return false;
    }
		
	
	target->SetDisconnected( true );
	avatar->Send( "Your target has been disconnected.\n\r" ); 
	return true;
}

// Make Admin
CmdChangeCmdGroup::CmdChangeCmdGroup( )
{
	SetName("changeperm"); // change permissions
	SetGroup("imp");
	SetEnabled( true );
}

bool CmdChangeCmdGroup::Execute( Char * avatar, const string &args )
{
   string name, s, arg;
   Avatar *target = NULL;
   
   // check args
   if( args.empty() )
   {
     avatar->Send("Syntax: changeperm <player> <perms>\n\r");
     avatar->Send("Possible perms (in order): player, admin, enforcer\n\r");
     return false;
   }
   
   split( args, name, arg );

   if ( (target = World::Instance().FindAvatar(name)) == NULL )
   {
      avatar->Send("Target not found.\n\r" );
      return false;
   }
   
   if ( arg.empty() )
   {
     avatar->Send("They must have -some- permission.\n\r" );
     return false;
   }

   // someone trying to set an imp
   if ( arg.find( "imp" ) != string::npos )
   {
     string s;

     s << "IMM WARNING: " << avatar->Get("name") << "(IP: " << avatar->GetSocket()->GetSocketIP()
     << ") tried to change permissions of " << target->Get("name") << "(IP: " << target->GetSocket()->GetSocketIP()
     << ") to " << arg << ".";

     glog( s.c_str() ); // log it
     
     avatar->Send("Implementors must be added manually!\n\r" );
     return false;
   }

   target->Set( "group", arg );
   target->Save();

   // send messages
   s = "\n\rYour command permissions have been changed by ";
   s << avatar->Get("name") << "!\n\r";
   s << "\n\rThey are now:\n\r" << arg << "\n\r";
   target->Send(s);
   
   s = "\n\r";
   s << target->Get("name") << "'s permissions changed to:\n\r" << arg << "\n\r";
   
   avatar->Send(s);
}