[6844] Daily quest fixes.
[getmangos.git] / src / game / AccountMgr.cpp
blob459cdbeac435acedb1061b469cb8d1850c05cce6
1 /*
2 * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "AccountMgr.h"
20 #include "Database/DatabaseEnv.h"
21 #include "ObjectAccessor.h"
22 #include "Player.h"
23 #include "Policies/SingletonImp.h"
24 #include "Util.h"
26 #ifdef DO_POSTGRESQL
27 extern DatabasePostgre loginDatabase;
28 #else
29 extern DatabaseMysql loginDatabase;
30 #endif
32 INSTANTIATE_SINGLETON_1(AccountMgr);
34 AccountMgr::AccountMgr()
37 AccountMgr::~AccountMgr()
40 AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password)
42 if(utf8length(username) > MAX_ACCOUNT_STR)
43 return AOR_NAME_TOO_LONG; // username's too long
45 normilizeString(username);
46 normilizeString(password);
48 loginDatabase.escape_string(username);
49 loginDatabase.escape_string(password);
51 QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE username = '%s'", username.c_str());
52 if(result)
54 delete result;
55 return AOR_NAME_ALREDY_EXIST; // username does already exist
58 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()))
59 return AOR_DB_INTERNAL_ERROR; // unexpected error
60 loginDatabase.Execute("INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist,account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL");
62 return AOR_OK; // everything's fine
65 AccountOpResult AccountMgr::DeleteAccount(uint32 accid)
67 QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
68 if(!result)
69 return AOR_NAME_NOT_EXIST; // account doesn't exist
70 delete result;
72 result = CharacterDatabase.PQuery("SELECT guid FROM characters WHERE account='%d'",accid);
73 if (result)
77 Field *fields = result->Fetch();
78 uint32 guidlo = fields[0].GetUInt32();
79 uint64 guid = MAKE_NEW_GUID(guidlo, 0, HIGHGUID_PLAYER);
81 // kick if player currently
82 if(Player* p = ObjectAccessor::FindPlayer(guid))
84 WorldSession* s = p->GetSession();
85 s->KickPlayer(); // mark session to remove at next session list update
86 s->LogoutPlayer(false); // logout player without waiting next session list update
89 Player::DeleteFromDB(guid, accid, false); // no need to update realm characters
90 } while (result->NextRow());
92 delete result;
95 // table realm specific but common for all characters of account for realm
96 CharacterDatabase.PExecute("DELETE FROM character_tutorial WHERE account = '%u'",accid);
98 loginDatabase.BeginTransaction();
100 bool res =
101 loginDatabase.PExecute("DELETE FROM account WHERE id='%d'", accid) &&
102 loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid='%d'", accid);
104 loginDatabase.CommitTransaction();
106 if(!res)
107 return AOR_DB_INTERNAL_ERROR; // unexpected error;
109 return AOR_OK;
112 AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname, std::string new_passwd)
114 QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
115 if(!result)
116 return AOR_NAME_NOT_EXIST; // account doesn't exist
117 delete result;
119 if(utf8length(new_uname) > MAX_ACCOUNT_STR)
120 return AOR_NAME_TOO_LONG;
122 if(utf8length(new_passwd) > MAX_ACCOUNT_STR)
123 return AOR_PASS_TOO_LONG;
125 normilizeString(new_uname);
126 normilizeString(new_passwd);
128 loginDatabase.escape_string(new_uname);
129 loginDatabase.escape_string(new_passwd);
130 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))
131 return AOR_DB_INTERNAL_ERROR; // unexpected error
133 return AOR_OK;
136 AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd)
138 QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
139 if(!result)
140 return AOR_NAME_NOT_EXIST; // account doesn't exist
141 delete result;
143 if (utf8length(new_passwd) > MAX_ACCOUNT_STR)
144 return AOR_PASS_TOO_LONG;
146 normilizeString(new_passwd);
148 loginDatabase.escape_string(new_passwd);
149 if(!loginDatabase.PExecute("UPDATE account SET sha_pass_hash=SHA1(CONCAT(username,':','%s')) WHERE id='%d'", new_passwd.c_str(), accid))
150 return AOR_DB_INTERNAL_ERROR; // unexpected error
152 return AOR_OK;
155 uint32 AccountMgr::GetId(std::string username)
157 loginDatabase.escape_string(username);
158 QueryResult *result = loginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'", username.c_str());
159 if(!result)
160 return 0;
161 else
163 uint32 id = (*result)[0].GetUInt32();
164 delete result;
165 return id;
169 uint32 AccountMgr::GetSecurity(uint32 acc_id)
171 QueryResult *result = loginDatabase.PQuery("SELECT gmlevel FROM account WHERE id = '%u'", acc_id);
172 if(result)
174 uint32 sec = (*result)[0].GetUInt32();
175 delete result;
176 return sec;
179 return 0;
182 bool AccountMgr::GetName(uint32 acc_id, std::string &name)
184 QueryResult *result = loginDatabase.PQuery("SELECT username FROM account WHERE id = '%u'", acc_id);
185 if(result)
187 name = (*result)[0].GetCppString();
188 delete result;
189 return true;
192 return false;
195 bool AccountMgr::CheckPassword(uint32 accid, std::string passwd)
197 normilizeString(passwd);
198 loginDatabase.escape_string(passwd);
200 QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash=SHA1(CONCAT(username,':','%s'))", accid, passwd.c_str());
201 if (result)
203 delete result;
204 return true;
207 return false;
210 bool AccountMgr::normilizeString(std::string& utf8str)
212 wchar_t wstr_buf[MAX_ACCOUNT_STR+1];
214 size_t wstr_len = MAX_ACCOUNT_STR;
215 if(!Utf8toWStr(utf8str,wstr_buf,wstr_len))
216 return false;
218 std::transform( &wstr_buf[0], wstr_buf+wstr_len, &wstr_buf[0], wcharToUpperOnlyLatin );
220 return WStrToUtf8(wstr_buf,wstr_len,utf8str);