#include "handler.h"
#include "avatar.h"
#include "world.h"
#include "stringutil.h"
#include "commandTable.h"
#include "timestamp.h"
#include "room.h"
#include <iostream>
#include <cstring>
#include <list>
using namespace std;
void GetNameHandler::Enter( Avatar * avatar )
{
}
void GetNameHandler::Exit( Avatar * avatar )
{
delete this;
return;
}
void GetNameHandler::Handle( Avatar * avatar, const string &input) {
if ( input.empty() )
return;
if ( !avatar->SetName( input ) ) {
avatar->Send( "Names must be 3-15 characters in length.\n\r" );
return;
}
avatar->ReplaceHandler( new CheckNameHandler );
}
string GetNameHandler::Prompt( Avatar * avatar ) {
return "Give us a name: ";
}
void InputHandler::Enter( Avatar * avatar )
{
Room *r = NULL;
if ( (r = World::Instance().FindRoom(avatar->Get("last_room"))) == NULL )
r = World::Instance().FindRoom(ROOM_LIMBO);
r->InsertAvatar(avatar,true);
}
void InputHandler::Exit( Avatar * avatar ) {
delete this;
}
void InputHandler::Handle( Avatar * avatar, const string &input )
{
if ( input.empty() )
return;
CommandTable::Instance().Execute( avatar, input );
}
string InputHandler::Prompt( Avatar * avatar )
{
string buf;
string prompt;
prompt = avatar->Get( "prompt" );
if ( prompt.empty() )
prompt = "%R> ";
for ( string::iterator cChar = prompt.begin(); cChar != prompt.end(); ++cChar ) {
if ( (*cChar) == '%' )
{
++cChar;
switch ( (*cChar) )
{
case 'R':
if ( avatar->_room )
buf << avatar->_room->Get("name");
else
buf << "The Void";
break;
case 'T':
buf << Timestamp::Instance().GetTime();
break;
case 's':
buf << ' ';
break;
case 'c':
buf << "\n\r";
break;
case '%':
buf << '%';
break;
default:
string buf2;
buf2 << "Invalid escape code: " << (*cChar) << "\n\r";
avatar->Send( buf2 );
}
} else
{
buf << (*cChar);
}
}
buf << "{x";
return buf;
}
void CheckNameHandler::Enter( Avatar * avatar )
{
if ( !avatar->Load() )
avatar->Send( "That username does not exist.\n\r" );
else
{
string name;
avatar->Send( "Username found.\n\r" );
avatar->ReplaceHandler( new GetPasswordHandler );
}
}
void CheckNameHandler::Exit( Avatar * avatar )
{
delete this;
}
void CheckNameHandler::Handle( Avatar * avatar, const string &input)
{
if ( input.empty() )
return;
switch ( input[0] ) {
case 'Y':
case 'y':
avatar->Send( "User created.\n\r" );
avatar->ReplaceHandler( new GetPasswordHandler );
break;
case 'n':
case 'N':
avatar->Send( "User not created.\n\r" );
avatar->ReplaceHandler( new GetNameHandler );
break;
}
}
string CheckNameHandler::Prompt( Avatar * avatar ) {
return "Create a new User? [Y/N] ";
}
string thePassword;
int tries = 0;
void GetPasswordHandler::Enter( Avatar * avatar ) {
}
void GetPasswordHandler::Exit( Avatar * avatar ) {
delete this;
}
void GetPasswordHandler::Handle( Avatar * avatar, const string &input )
{
list< Avatar *>::iterator a_it;
if ( input.empty() )
return;
thePassword = avatar->Get( "password" );
if ( thePassword.empty() )
{
if ( avatar->Set( "password", avatar->EncryptPassword( input ) ) )
avatar->Send( "Password Acceptable.\n\r" );
}
else
{
if ( avatar->VerifyPassword( input ) )
{
avatar->Send( "Passwords match.\n\r\n\r" );
avatar->Set( "login", Timestamp::Instance().GetDateTime() );
avatar->Save();
avatar->Load();
for ( a_it = World::Instance()._avatarList.begin(); a_it != World::Instance()._avatarList.end(); ++a_it ) {
if ( ( (*a_it) != avatar ) && ( (*a_it)->GetStatus() == CONNECTED ) && ( (*a_it)->Get( "name" ) == avatar->Get( "name" ) ) ) {
int previous_descriptor = (*a_it)->GetSocket()->GetDescriptor();
(*a_it)->GetSocket()->SetDescriptor( avatar->GetSocket()->GetDescriptor() );
avatar->GetSocket()->SetDescriptor( previous_descriptor );
avatar->SetDisconnected( true );
(*a_it)->Send( "You have reconnected.\n\r" );
(*a_it)->Set( "login", Timestamp::Instance().GetDateTime() );
string buf;
buf << "## " << avatar->Get( "name" ) << " has reconnected.\n\r";
World::Instance().Broadcast( buf, WCONNECTED );
cout << avatar->Get( "name" ) << " has reconnected @ " << Timestamp::Instance().GetDateTime() << "\n\r";
return;
}
}
string buf;
avatar->SetStatus( CONNECTED );
buf << "## " << avatar->Get( "name" ) << " has connected.\n\r";
World::Instance().Broadcast( buf, WCONNECTED );
cout << avatar->Get( "name" ) << " has connected @ " << Timestamp::Instance().GetDateTime() << "\n\r";
avatar->ReplaceHandler( new InputHandler );
}
else
{
tries++;
avatar->Send( "Passwords do not match.\n\r" );
thePassword.erase();
switch ( tries )
{
default:
case 3:
avatar->Send( "No more chances.\n\r" );
avatar->ClearPassword();
avatar->ReplaceHandler( new GetNameHandler );
tries = 0;
break;
case 2: avatar->Send( "1 more chance.\n\r" ); break;
case 1: avatar->Send( "2 more chances.\n\r" ); break;
case 0: avatar->Send( "3 more chances.\n\r" ); break;
}
}
}
}
string GetPasswordHandler::Prompt( Avatar * avatar )
{
return "Enter password: ";
}