[7770] Prevent access to possible deleted aura's spell proto in Aura::HandleModStealth.
[AHbot.git] / src / game / AccountMgr.cpp
bloba10b0575f6914b6a70a87e589dc757f331e9a918
1 /*
2 * Copyright (C) 2005-2009 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 extern DatabaseType loginDatabase;
28 INSTANTIATE_SINGLETON_1(AccountMgr);
30 AccountMgr::AccountMgr()
33 AccountMgr::~AccountMgr()
36 AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password)
38 if(utf8length(username) > MAX_ACCOUNT_STR)
39 return AOR_NAME_TOO_LONG; // username's too long
41 normilizeString(username);
42 normilizeString(password);
44 loginDatabase.escape_string(username);
45 loginDatabase.escape_string(password);
47 QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE username = '%s'", username.c_str());
48 if(result)
50 delete result;
51 return AOR_NAME_ALREDY_EXIST; // username does already exist
54 if(!loginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate) VALUES('%s',SHA1("_CONCAT3_("'%s'","':'","'%s'")"),NOW())", username.c_str(), username.c_str(), password.c_str()))
55 return AOR_DB_INTERNAL_ERROR; // unexpected error
56 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");
58 return AOR_OK; // everything's fine
61 AccountOpResult AccountMgr::DeleteAccount(uint32 accid)
63 QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
64 if(!result)
65 return AOR_NAME_NOT_EXIST; // account doesn't exist
66 delete result;
68 result = CharacterDatabase.PQuery("SELECT guid FROM characters WHERE account='%d'",accid);
69 if (result)
73 Field *fields = result->Fetch();
74 uint32 guidlo = fields[0].GetUInt32();
75 uint64 guid = MAKE_NEW_GUID(guidlo, 0, HIGHGUID_PLAYER);
77 // kick if player currently
78 if(Player* p = ObjectAccessor::FindPlayer(guid))
80 WorldSession* s = p->GetSession();
81 s->KickPlayer(); // mark session to remove at next session list update
82 s->LogoutPlayer(false); // logout player without waiting next session list update
85 Player::DeleteFromDB(guid, accid, false); // no need to update realm characters
86 } while (result->NextRow());
88 delete result;
91 // table realm specific but common for all characters of account for realm
92 CharacterDatabase.PExecute("DELETE FROM character_tutorial WHERE account = '%u'",accid);
94 loginDatabase.BeginTransaction();
96 bool res =
97 loginDatabase.PExecute("DELETE FROM account WHERE id='%d'", accid) &&
98 loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid='%d'", accid);
100 loginDatabase.CommitTransaction();
102 if(!res)
103 return AOR_DB_INTERNAL_ERROR; // unexpected error;
105 return AOR_OK;
108 AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname, std::string new_passwd)
110 QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
111 if(!result)
112 return AOR_NAME_NOT_EXIST; // account doesn't exist
113 delete result;
115 if(utf8length(new_uname) > MAX_ACCOUNT_STR)
116 return AOR_NAME_TOO_LONG;
118 if(utf8length(new_passwd) > MAX_ACCOUNT_STR)
119 return AOR_PASS_TOO_LONG;
121 normilizeString(new_uname);
122 normilizeString(new_passwd);
124 loginDatabase.escape_string(new_uname);
125 loginDatabase.escape_string(new_passwd);
126 if(!loginDatabase.PExecute("UPDATE account SET username='%s',sha_pass_hash=SHA1("_CONCAT3_("'%s'","':'","'%s'")") WHERE id='%d'", new_uname.c_str(), new_uname.c_str(), new_passwd.c_str(), accid))
127 return AOR_DB_INTERNAL_ERROR; // unexpected error
129 return AOR_OK;
132 AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd)
134 QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
135 if(!result)
136 return AOR_NAME_NOT_EXIST; // account doesn't exist
137 delete result;
139 if (utf8length(new_passwd) > MAX_ACCOUNT_STR)
140 return AOR_PASS_TOO_LONG;
142 normilizeString(new_passwd);
144 loginDatabase.escape_string(new_passwd);
145 if(!loginDatabase.PExecute("UPDATE account SET sha_pass_hash=SHA1("_CONCAT3_("username","':'","'%s'")") WHERE id='%d'", new_passwd.c_str(), accid))
146 return AOR_DB_INTERNAL_ERROR; // unexpected error
148 return AOR_OK;
151 uint32 AccountMgr::GetId(std::string username)
153 loginDatabase.escape_string(username);
154 QueryResult *result = loginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'", username.c_str());
155 if(!result)
156 return 0;
157 else
159 uint32 id = (*result)[0].GetUInt32();
160 delete result;
161 return id;
165 uint32 AccountMgr::GetSecurity(uint32 acc_id)
167 QueryResult *result = loginDatabase.PQuery("SELECT gmlevel FROM account WHERE id = '%u'", acc_id);
168 if(result)
170 uint32 sec = (*result)[0].GetUInt32();
171 delete result;
172 return sec;
175 return 0;
178 bool AccountMgr::GetName(uint32 acc_id, std::string &name)
180 QueryResult *result = loginDatabase.PQuery("SELECT username FROM account WHERE id = '%u'", acc_id);
181 if(result)
183 name = (*result)[0].GetCppString();
184 delete result;
185 return true;
188 return false;
191 bool AccountMgr::CheckPassword(uint32 accid, std::string passwd)
193 normilizeString(passwd);
194 loginDatabase.escape_string(passwd);
196 QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash=SHA1("_CONCAT3_("username","':'","'%s'")")", accid, passwd.c_str());
197 if (result)
199 delete result;
200 return true;
203 return false;
206 bool AccountMgr::normilizeString(std::string& utf8str)
208 wchar_t wstr_buf[MAX_ACCOUNT_STR+1];
210 size_t wstr_len = MAX_ACCOUNT_STR;
211 if(!Utf8toWStr(utf8str,wstr_buf,wstr_len))
212 return false;
214 std::transform( &wstr_buf[0], wstr_buf+wstr_len, &wstr_buf[0], wcharToUpperOnlyLatin );
216 return WStrToUtf8(wstr_buf,wstr_len,utf8str);