aboutsummaryrefslogtreecommitdiff
path: root/src/game/AccountMgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/AccountMgr.cpp')
-rw-r--r--src/game/AccountMgr.cpp195
1 files changed, 195 insertions, 0 deletions
diff --git a/src/game/AccountMgr.cpp b/src/game/AccountMgr.cpp
new file mode 100644
index 00000000000..3b14db46dba
--- /dev/null
+++ b/src/game/AccountMgr.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "AccountMgr.h"
+#include "Database/DatabaseEnv.h"
+#include "ObjectMgr.h"
+#include "Player.h"
+#include "Policies/SingletonImp.h"
+#include "Util.h"
+
+#ifdef DO_POSTGRESQL
+extern DatabasePostgre loginDatabase;
+#else
+extern DatabaseMysql loginDatabase;
+#endif
+
+INSTANTIATE_SINGLETON_1(AccountMgr);
+
+AccountMgr::AccountMgr()
+{}
+
+AccountMgr::~AccountMgr()
+{}
+
+AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password)
+{
+ if(utf8length(username) > MAX_ACCOUNT_STR)
+ return AOR_NAME_TOO_LONG; // username's too long
+
+ normilizeString(username);
+ normilizeString(password);
+
+ loginDatabase.escape_string(username);
+ loginDatabase.escape_string(password);
+
+ QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE username = '%s'", username.c_str());
+ if(result)
+ {
+ delete result;
+ return AOR_NAME_ALREDY_EXIST; // username does already exist
+ }
+
+ if(!loginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate) VALUES('%s',SHA1(CONCAT('%s',':','%s')),NOW())", username.c_str(), username.c_str(), password.c_str()))
+ return AOR_DB_INTERNAL_ERROR; // unexpected error
+ loginDatabase.Execute("INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM account, realmlist WHERE account.id NOT IN (SELECT acctid FROM realmcharacters)");
+
+ return AOR_OK; // everything's fine
+}
+
+AccountOpResult AccountMgr::DeleteAccount(uint32 accid)
+{
+ QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
+ if(!result)
+ return AOR_NAME_NOT_EXIST; // account doesn't exist
+ delete result;
+
+ result = CharacterDatabase.PQuery("SELECT guid FROM characters WHERE account='%d'",accid);
+ if (result)
+ {
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 guidlo = fields[0].GetUInt32();
+ uint64 guid = MAKE_NEW_GUID(guidlo, 0, HIGHGUID_PLAYER);
+
+ // kick if player currently
+ if(Player* p = objmgr.GetPlayer(guid))
+ {
+ WorldSession* s = p->GetSession();
+ s->KickPlayer(); // mark session to remove at next session list update
+ s->LogoutPlayer(false); // logout player without waiting next session list update
+ }
+
+ Player::DeleteFromDB(guid, accid, false); // no need to update realm characters
+ } while (result->NextRow());
+
+ delete result;
+ }
+
+ // table realm specific but common for all characters of account for realm
+ CharacterDatabase.PExecute("DELETE FROM character_tutorial WHERE account = '%u'",accid);
+
+ loginDatabase.BeginTransaction();
+
+ bool res =
+ loginDatabase.PExecute("DELETE FROM account WHERE id='%d'", accid) &&
+ loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid='%d'", accid);
+
+ loginDatabase.CommitTransaction();
+
+ if(!res)
+ return AOR_DB_INTERNAL_ERROR; // unexpected error;
+
+ return AOR_OK;
+}
+
+AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname, std::string new_passwd)
+{
+ QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
+ if(!result)
+ return AOR_NAME_NOT_EXIST; // account doesn't exist
+ delete result;
+
+ if(utf8length(new_uname) > MAX_ACCOUNT_STR)
+ return AOR_NAME_TOO_LONG;
+
+ if(utf8length(new_passwd) > MAX_ACCOUNT_STR)
+ return AOR_PASS_TOO_LONG;
+
+ normilizeString(new_uname);
+ normilizeString(new_passwd);
+
+ loginDatabase.escape_string(new_uname);
+ loginDatabase.escape_string(new_passwd);
+ if(!loginDatabase.PExecute("UPDATE account SET username='%s',sha_pass_hash=SHA1(CONCAT('%s',':','%s')) WHERE id='%d'", new_uname.c_str(), new_uname.c_str(), new_passwd.c_str(), accid))
+ return AOR_DB_INTERNAL_ERROR; // unexpected error
+
+ return AOR_OK;
+}
+
+AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd)
+{
+ QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
+ if(!result)
+ return AOR_NAME_NOT_EXIST; // account doesn't exist
+ delete result;
+
+ if (utf8length(new_passwd) > MAX_ACCOUNT_STR)
+ return AOR_PASS_TOO_LONG;
+
+ normilizeString(new_passwd);
+
+ loginDatabase.escape_string(new_passwd);
+ if(!loginDatabase.PExecute("UPDATE account SET sha_pass_hash=SHA1(CONCAT(username,':','%s')) WHERE id='%d'", new_passwd.c_str(), accid))
+ return AOR_DB_INTERNAL_ERROR; // unexpected error
+
+ return AOR_OK;
+}
+
+uint32 AccountMgr::GetId(std::string username)
+{
+ loginDatabase.escape_string(username);
+ QueryResult *result = loginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'", username.c_str());
+ if(!result)
+ return 0;
+ else
+ {
+ uint32 id = (*result)[0].GetUInt32();
+ delete result;
+ return id;
+ }
+}
+
+bool AccountMgr::CheckPassword(uint32 accid, std::string passwd)
+{
+ normilizeString(passwd);
+ loginDatabase.escape_string(passwd);
+
+ QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash=SHA1(CONCAT(username,':','%s'))", accid, passwd.c_str());
+ if (result)
+ {
+ delete result;
+ return true;
+ }
+
+ return false;
+}
+
+bool AccountMgr::normilizeString(std::string& utf8str)
+{
+ wchar_t wstr_buf[MAX_ACCOUNT_STR+1];
+
+ size_t wstr_len = MAX_ACCOUNT_STR;
+ if(!Utf8toWStr(utf8str,wstr_buf,wstr_len))
+ return false;
+
+ std::transform( &wstr_buf[0], wstr_buf+wstr_len, &wstr_buf[0], wcharToUpperOnlyLatin );
+
+ return WStrToUtf8(wstr_buf,wstr_len,utf8str);
+}