summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYohann Ferreira <bertram@cegetel.net>2005-12-11 22:31:28 +0000
committerYohann Ferreira <bertram@cegetel.net>2005-12-11 22:31:28 +0000
commit5ef4627a825d2c1ffd59a8ad33d05a6d72240a69 (patch)
treec1103c9a0dfa660f95277823827b5b77a6aa9097
parent85e4cfdb4043ea44ad1cd74041c4589b035fc65b (diff)
downloadmanaserv-5ef4627a825d2c1ffd59a8ad33d05a6d72240a69.tar.gz
manaserv-5ef4627a825d2c1ffd59a8ad33d05a6d72240a69.tar.bz2
manaserv-5ef4627a825d2c1ffd59a8ad33d05a6d72240a69.tar.xz
manaserv-5ef4627a825d2c1ffd59a8ad33d05a6d72240a69.zip
Added logout and character deletion support. Changed the response code as trying to login when already logged in.
-rw-r--r--ChangeLog5
-rw-r--r--src/account.cpp23
-rw-r--r--src/account.h8
-rw-r--r--src/accounthandler.cpp81
-rw-r--r--src/client.cpp39
-rw-r--r--src/dalstorage.cpp61
-rw-r--r--src/defines.h4
-rw-r--r--src/main.cpp2
8 files changed, 208 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 41e493d7..0687ccd9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2005-12-11 Yohann Ferreira <bertram@cegetel.net>
+ * src/accounthandler.cpp, src/main.cpp, src/account.h,
+ src/account.cpp, src/dalstorage.cpp, src/client.cpp,
+ src/defines.h: Added Logout, and character deletion support.
+ Also changed the response code when trying to login when already
+ logged.
* src/accounthandler.cpp, src/main.cpp, src/dalstorage.cpp,
src/client.cpp, src/connectionhandler.cpp, src/defines.h:
Added unregistering, checking on character's name and email
diff --git a/src/account.cpp b/src/account.cpp
index bf20ac34..86815ed4 100644
--- a/src/account.cpp
+++ b/src/account.cpp
@@ -176,6 +176,29 @@ Account::addCharacter(BeingPtr character)
}
}
+/**
+ * Remove a character.
+ */
+bool
+Account::delCharacter(std::string name)
+{
+ Beings::iterator it =
+ std::find_if(mCharacters.begin(),
+ mCharacters.end(),
+ std::bind2nd(obj_name_is<BeingPtr>(), name)
+ );
+
+ if (it != mCharacters.end()) {
+ // Exists, delete it.
+ mCharacters.erase(it++);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
/**
* Get all the characters.
diff --git a/src/account.h b/src/account.h
index f45ec7c4..5cb57ede 100644
--- a/src/account.h
+++ b/src/account.h
@@ -176,6 +176,14 @@ class Account
void
addCharacter(BeingPtr character);
+ /**
+ * Remove a character.
+ *
+ * @param name The character's name to delete.
+ */
+ bool
+ delCharacter(std::string name);
+
/**
* Get all the characters.
diff --git a/src/accounthandler.cpp b/src/accounthandler.cpp
index c2e2df5e..0ad9c1ba 100644
--- a/src/accounthandler.cpp
+++ b/src/accounthandler.cpp
@@ -69,7 +69,7 @@ void AccountHandler::receiveMessage(NetComputer &computer, MessageIn &message)
<< "." << std::endl;
std::cout << "Please logout first." << std::endl;
result.writeShort(SMSG_LOGIN_ERROR);
- result.writeShort(LOGIN_UNKNOWN);
+ result.writeShort(LOGIN_ALREADY_LOGGED);
break;
}
@@ -115,6 +115,37 @@ void AccountHandler::receiveMessage(NetComputer &computer, MessageIn &message)
}
break;
+ case CMSG_LOGOUT:
+ {
+ if ( computer.getAccount() == NULL )
+ {
+ std::cout << "Can't logout. Not even logged in." << std::endl;
+ result.writeShort(SMSG_LOGOUT_ERROR);
+ result.writeByte(LOGOUT_UNSUCCESSFULL);
+ }
+ else
+ {
+ std::string username = computer.getAccount()->getName();
+ if ( username == "" )
+ {
+ std::cout << "Account without name ? Logged out anyway..." << std::endl;
+ computer.setCharacter(NULL);
+ computer.setAccount(NULL);
+ result.writeShort(SMSG_LOGOUT_ERROR);
+ result.writeByte(LOGOUT_UNKNOWN);
+ }
+ else
+ {
+ std::cout << computer.getAccount()->getName() << " logs out." << std::endl;
+ computer.setCharacter(NULL);
+ computer.setAccount(NULL);
+ result.writeShort(SMSG_LOGOUT_CONFIRM);
+ result.writeByte(LOGOUT_OK);
+ }
+ }
+ }
+ break;
+
case CMSG_REGISTER:
{
std::string username = message.readString();
@@ -319,8 +350,54 @@ void AccountHandler::receiveMessage(NetComputer &computer, MessageIn &message)
std::cout << "Selected Character " << int(charNum)
<< " : " <<
computer.getCharacter()->getName() << std::endl;
+ }
+ break;
+
+ case CMSG_CHAR_DELETE:
+ {
+ if (computer.getAccount() == NULL)
+ {
+ result.writeShort(SMSG_CHAR_DELETE_RESPONSE);
+ result.writeByte(DELETE_NOLOGIN);
+ std::cout << "Not logged in. Can't delete a Character." << std::endl;
+ break; // not logged in
+ }
+
+ unsigned char charNum = message.readByte();
+
+ tmwserv::Beings &chars = computer.getAccount()->getCharacters();
+ result.writeShort(SMSG_CHAR_DELETE_RESPONSE);
+ if ( chars.size() == 0 )
+ {
+ result.writeByte(DELETE_NO_MORE_CHARACTERS);
+ std::cout << "Character Deletion : No characters in this account." << std::endl;
+ break;
+ }
+ // Character ID = 0 to Number of Characters - 1.
+ if (charNum >= chars.size()) {
+ // invalid char selection
+ result.writeByte(DELETE_INVALID_NAME);
+ std::cout << "Character Deletion : Selection out of ID range." << std::endl;
+ break;
+ }
+
+ // Delete the character
+ // if the character to delete is the current character, get off of it in
+ // memory.
+ if ( computer.getCharacter() != NULL )
+ {
+ if ( computer.getCharacter()->getName() == chars[charNum].get()->getName() )
+ {
+ computer.setCharacter(NULL);
+ }
+ }
+
+ std::string deletedCharacter = chars[charNum].get()->getName();
+ computer.getAccount()->delCharacter(deletedCharacter);
+ store.flush();
+ std::cout << deletedCharacter << ": Character deleted..." << std::endl;
+ result.writeByte(DELETE_OK);
- //TODO: Add the character in the database and flush.
}
break;
diff --git a/src/client.cpp b/src/client.cpp
index c2115ce6..8bbcce4e 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -51,12 +51,14 @@ int main(int argc, char *argv[])
printf ("1) Register\n");
printf ("2) Unregister\n");
printf ("3) Login\n");
- printf ("4) Chat\n");
- printf ("5) Create character\n");
- printf ("6) Character selection\n");
- printf ("7) Move character\n");
- printf ("8) Equip item\n");
- printf ("9) Ruby expression\n");
+ printf ("4) Logout\n");
+ printf ("5) Chat\n");
+ printf ("6) Create character\n");
+ printf ("7) Character selection\n");
+ printf ("8) Delete Character\n");
+ printf ("9) Move character\n");
+ printf ("10) Equip item\n");
+ printf ("11) Ruby expression\n");
printf ("Choose your option: ");
std::cin >> answer;
@@ -98,6 +100,12 @@ int main(int argc, char *argv[])
break;
case 4:
+ // Logout
+ msg.writeShort(CMSG_LOGOUT);
+ std::cout << "Logout" << std::endl;
+ break;
+
+ case 5:
// Chat
msg.writeShort(CMSG_SAY);
printf("\nChat: ", line);
@@ -107,7 +115,7 @@ int main(int argc, char *argv[])
responseRequired = false;
break;
- case 5:
+ case 6:
{
// Create character
msg.writeShort(CMSG_CHAR_CREATE);
@@ -117,7 +125,7 @@ int main(int argc, char *argv[])
msg.writeByte(0);
} break;
- case 6:
+ case 7:
{
// Select character
msg.writeShort(CMSG_CHAR_SELECT);
@@ -126,7 +134,16 @@ int main(int argc, char *argv[])
msg.writeByte(atoi(line));
} break;
- case 7:
+ case 8:
+ {
+ // Delete character
+ msg.writeShort(CMSG_CHAR_DELETE);
+ printf("\nCharacter ID: ");
+ std::cin >> line;
+ msg.writeByte(atoi(line));
+ } break;
+
+ case 9:
{
// Move character
long x, y;
@@ -142,7 +159,7 @@ int main(int argc, char *argv[])
responseRequired = false;
} break;
- case 8:
+ case 10:
{
// Equip
unsigned int itemId;
@@ -156,7 +173,7 @@ int main(int argc, char *argv[])
msg.writeByte(slot);
} break;
- case 9:
+ case 11:
{
std::cout << "Expr: ";
std::cin >> line;
diff --git a/src/dalstorage.cpp b/src/dalstorage.cpp
index 721b0b72..5d45ba56 100644
--- a/src/dalstorage.cpp
+++ b/src/dalstorage.cpp
@@ -625,7 +625,8 @@ DALStorage::_updAccount(const AccountPtr& account)
// doublecheck that this account already exists in the database
// and therefore its status must be AS_ACC_TO_UPDATE.
if ((account_it->second).status != AS_ACC_TO_UPDATE) {
- return; // should we throw an exception here instead?
+ return; // Should we throw an exception here instead? No, because this can happen
+ // without any bad consequences as long as we return -- Bertram.
}
// update the account.
@@ -709,6 +710,62 @@ DALStorage::_updAccount(const AccountPtr& account)
// TODO: inventories.
}
+
+ // Existing characters in memory have been inserted or updated in database.
+ // Now, let's remove those who are no more in memory from database.
+
+ // specialize the string_to functor to convert
+ // a string to an unsigned int.
+ string_to<unsigned short> toUint;
+
+ std::ostringstream sql4;
+ sql4 << "select name, id from " << CHARACTERS_TBL_NAME
+ << " where user_id = '" << (account_it->second).id << "';";
+ const RecordSet& charInMemInfo = mDb->execSql(sql4.str());
+
+ // We compare chars from memory and those existing in db,
+ // And delete those not in mem but existing in db.
+ bool charFound;
+ for ( unsigned int i = 0; i < charInMemInfo.rows(); ++i) // in database
+ {
+ charFound = false;
+ it = characters.begin();
+ for (; it != it_end; ++it) // In memory
+ {
+ if ( charInMemInfo(i, 0) == (*it)->getName() )
+ {
+ charFound = true;
+ break;
+ }
+ }
+ if ( !charFound )
+ {
+ // The char is db but not in memory,
+ // It will be removed from database.
+ // We store the id of the char to delete
+ // Because as deleted, the RecordSet is also emptied
+ // That creates an error.
+ unsigned int charId = toUint(charInMemInfo(i, 1));
+
+ // delete the inventory.
+ std::ostringstream sql5;
+ sql5 << "delete from ";
+ sql5 << INVENTORIES_TBL_NAME;
+ sql5 << " where owner_id = '";
+ sql5 << charId;
+ sql5 << "';";
+ mDb->execSql(sql5.str());
+
+ // now delete the character.
+ std::ostringstream sql6;
+ sql6 << "delete from ";
+ sql6 << CHARACTERS_TBL_NAME;
+ sql6 << " where id = '";
+ sql6 << charId;
+ sql6 << "';";
+ mDb->execSql(sql6.str());
+ }
+ }
}
@@ -769,6 +826,8 @@ DALStorage::_delAccount(const std::string& userName)
// TODO: we should start a transaction here so that in case of problem
// the lost of data would be minimized.
+ // db.set-transaction-type of this-db to db.manual-commit, for instance
+ // Agreed, but will sqlite support this ?
// actually removing data.
vector<string>::const_iterator it = charIds.begin();
diff --git a/src/defines.h b/src/defines.h
index 75991a63..a302796d 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -94,7 +94,8 @@ enum {
SMSG_LOGIN_ERROR = 0x0012,
SMSG_LOGIN_CONFIRM = 0x0013,
CMSG_LOGOUT = 0x0014,
- SMSG_LOGOUT_CONFIRM = 0x0015,
+ SMSG_LOGOUT_ERROR = 0x0015,
+ SMSG_LOGOUT_CONFIRM = 0x0016,
CMSG_CHAR_CREATE = 0x0020,
SMSG_CHAR_CREATE_RESPONSE = 0x0021,
CMSG_CHAR_DELETE = 0x0022,
@@ -154,6 +155,7 @@ enum {
LOGIN_SERVER_FULL,
LOGIN_ACCOUNT_BANNED,
LOGIN_ACCOUNT_REVIEW,
+ LOGIN_ALREADY_LOGGED,
LOGIN_UNKNOWN
};
diff --git a/src/main.cpp b/src/main.cpp
index b9cda372..3c2406f6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -227,10 +227,12 @@ int main(int argc, char *argv[])
// Register message handlers
connectionHandler.registerHandler(CMSG_LOGIN, accountHandler);
+ connectionHandler.registerHandler(CMSG_LOGOUT, accountHandler);
connectionHandler.registerHandler(CMSG_REGISTER, accountHandler);
connectionHandler.registerHandler(CMSG_UNREGISTER, accountHandler);
connectionHandler.registerHandler(CMSG_CHAR_CREATE, accountHandler);
connectionHandler.registerHandler(CMSG_CHAR_SELECT, accountHandler);
+ connectionHandler.registerHandler(CMSG_CHAR_DELETE, accountHandler);
connectionHandler.registerHandler(CMSG_SAY, chatHandler);
connectionHandler.registerHandler(CMSG_ANNOUNCE, chatHandler);