summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/Common.h38
-rw-r--r--src/server/apps/authserver/Server/AuthSession.cpp2
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.cpp5
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.h3
-rw-r--r--src/server/game/Accounts/AccountMgr.cpp39
-rw-r--r--src/server/game/Accounts/AccountMgr.h6
-rw-r--r--src/server/game/Server/WorldSocket.cpp26
7 files changed, 106 insertions, 13 deletions
diff --git a/src/common/Common.h b/src/common/Common.h
index 87ec6b4d2b..98f343a45e 100644
--- a/src/common/Common.h
+++ b/src/common/Common.h
@@ -61,6 +61,44 @@ enum AccountTypes
SEC_CONSOLE = 4 // must be always last in list, accounts must have less security level always also
};
+enum AccountFlag
+{
+ ACCOUNT_FLAG_GM = 0x1, // Account is GM
+ ACCOUNT_FLAG_NOKICK = 0x2, // NYI UNK
+ ACCOUNT_FLAG_COLLECTOR = 0x4, // NYI Collector's Edition
+ ACCOUNT_FLAG_TRIAL = 0x8, // NYI Trial account
+ ACCOUNT_FLAG_CANCELLED = 0x10, // NYI UNK
+ ACCOUNT_FLAG_IGR = 0x20, // NYI Internet Game Room (Internet cafe?)
+ ACCOUNT_FLAG_WHOLESALER = 0x40, // NYI UNK
+ ACCOUNT_FLAG_PRIVILEGED = 0x80, // NYI UNK
+ ACCOUNT_FLAG_EU_FORBID_ELV = 0x100, // NYI UNK
+ ACCOUNT_FLAG_EU_FORBID_BILLING = 0x200, // NYI UNK
+ ACCOUNT_FLAG_RESTRICTED = 0x400, // NYI UNK
+ ACCOUNT_FLAG_REFERRAL = 0x800, // NYI Recruit-A-Friend, either referer or referee
+ ACCOUNT_FLAG_BLIZZARD = 0x1000, // NYI UNK
+ ACCOUNT_FLAG_RECURRING_BILLING = 0x2000, // NYI UNK
+ ACCOUNT_FLAG_NOELECTUP = 0x4000, // NYI UNK
+ ACCOUNT_FLAG_KR_CERTIFICATE = 0x8000, // NYI Korean certificate?
+ ACCOUNT_FLAG_EXPANSION_COLLECTOR = 0x10000, // NYI TBC Collector's Edition
+ ACCOUNT_FLAG_DISABLE_VOICE = 0x20000, // NYI Can't join voice chat
+ ACCOUNT_FLAG_DISABLE_VOICE_SPEAK = 0x40000, // NYI Can't speak in voice chat
+ ACCOUNT_FLAG_REFERRAL_RESURRECT = 0x80000, // NYI Scroll of Resurrection
+ ACCOUNT_FLAG_EU_FORBID_CC = 0x100000, // NYI UNK
+ ACCOUNT_FLAG_OPENBETA_DELL = 0x200000, // NYI https://wowpedia.fandom.com/wiki/Dell_XPS_M1730_World_of_Warcraft_Edition
+ ACCOUNT_FLAG_PROPASS = 0x400000, // NYI UNK
+ ACCOUNT_FLAG_PROPASS_LOCK = 0x800000, // NYI Pro pass (arena tournament)
+ ACCOUNT_FLAG_PENDING_UPGRADE = 0x1000000, // NYI UNK
+ ACCOUNT_FLAG_RETAIL_FROM_TRIAL = 0x2000000, // NYI UNK
+ ACCOUNT_FLAG_EXPANSION2_COLLECTOR = 0x4000000, // NYI WotLK Collector's Edition
+ ACCOUNT_FLAG_OVERMIND_LINKED = 0x8000000, // NYI Linked with Battle.net account
+ ACCOUNT_FLAG_DEMOS = 0x10000000, // NYI UNK
+ ACCOUNT_FLAG_DEATH_KNIGHT_OK = 0x20000000, // NYI Has level 55 on account?
+ // Below might be StarCraft II related
+ ACCOUNT_FLAG_S2_REQUIRE_IGR = 0x40000000, // NYI UNK
+ ACCOUNT_FLAG_S2_TRIAL = 0x80000000, // NYI UNK
+ ACCOUNT_FLAG_S2_RESTRICTED = 0xFFFFFFFF // NYI UNK
+};
+
enum LocaleConstant
{
LOCALE_enUS = 0,
diff --git a/src/server/apps/authserver/Server/AuthSession.cpp b/src/server/apps/authserver/Server/AuthSession.cpp
index 945dd62a39..c59cfb13c2 100644
--- a/src/server/apps/authserver/Server/AuthSession.cpp
+++ b/src/server/apps/authserver/Server/AuthSession.cpp
@@ -531,7 +531,7 @@ bool AuthSession::HandleLogonProof()
proof.M2 = M2;
proof.cmd = AUTH_LOGON_PROOF;
proof.error = 0;
- proof.AccountFlags = 0x00800000; // 0x01 = GM, 0x08 = Trial, 0x00800000 = Pro pass (arena tournament)
+ proof.AccountFlags = ACCOUNT_FLAG_PROPASS_LOCK; // enum AccountFlag
proof.SurveyId = 0;
proof.LoginFlags = 0; // 0x1 = has account message
diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp
index 0933a22d70..95eb1f9cbc 100644
--- a/src/server/database/Database/Implementation/LoginDatabase.cpp
+++ b/src/server/database/Database/Implementation/LoginDatabase.cpp
@@ -43,7 +43,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
"LEFT JOIN account_banned ab ON ab.id = a.id AND ab.active = 1 "
"LEFT JOIN ip_banned ipb ON ipb.ip = ? "
"WHERE a.username = ? AND a.session_key IS NOT NULL", CONNECTION_ASYNC);
- PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT a.id, a.session_key, a.last_ip, a.locked, a.lock_country, a.expansion, a.mutetime, a.locale, a.recruiter, a.os, a.totaltime, "
+ PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT a.id, a.session_key, a.last_ip, a.locked, a.lock_country, a.expansion, a.Flags, a.mutetime, a.locale, a.recruiter, a.os, a.totaltime, "
"aa.gmlevel, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, r.id FROM account a LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID IN (-1, ?) "
"LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 LEFT JOIN account r ON a.id = r.recruiter WHERE a.username = ? "
"AND a.session_key IS NOT NULL ORDER BY aa.RealmID DESC LIMIT 1", CONNECTION_ASYNC);
@@ -101,6 +101,9 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_GET_USERNAME_BY_ID, "SELECT username FROM account WHERE id = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_CHECK_PASSWORD, "SELECT salt, verifier FROM account WHERE id = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_CHECK_PASSWORD_BY_NAME, "SELECT salt, verifier FROM account WHERE username = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_SEL_ACCOUNT_FLAG, "SELECT Flags FROM account WHERE id = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_UPD_ADD_ACCOUNT_FLAG, "UPDATE account SET Flags = Flags | ? WHERE id = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_UPD_REMOVE_ACCOUNT_FLAG, "UPDATE account SET Flags = Flags &~ ? WHERE id = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_PINFO, "SELECT a.username, aa.gmlevel, a.email, a.reg_mail, a.last_ip, DATE_FORMAT(a.last_login, '%Y-%m-%d %T'), a.mutetime, a.mutereason, a.muteby, a.failed_logins, a.locked, a.OS FROM account a LEFT JOIN account_access aa ON (a.id = aa.id AND (aa.RealmID = ? OR aa.RealmID = -1)) WHERE a.id = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_PINFO_BANS, "SELECT unbandate, bandate = unbandate, bannedby, banreason FROM account_banned WHERE id = ? AND active ORDER BY bandate ASC LIMIT 1", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_GM_ACCOUNTS, "SELECT a.username, aa.gmlevel FROM account a, account_access aa WHERE a.id=aa.id AND aa.gmlevel >= ? AND (aa.realmid = -1 OR aa.realmid = ?)", CONNECTION_SYNCH);
diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h
index 2ee0154f82..230e86452d 100644
--- a/src/server/database/Database/Implementation/LoginDatabase.h
+++ b/src/server/database/Database/Implementation/LoginDatabase.h
@@ -85,6 +85,9 @@ enum LoginDatabaseStatements : uint32
LOGIN_GET_USERNAME_BY_ID,
LOGIN_SEL_CHECK_PASSWORD,
LOGIN_SEL_CHECK_PASSWORD_BY_NAME,
+ LOGIN_SEL_ACCOUNT_FLAG,
+ LOGIN_UPD_ADD_ACCOUNT_FLAG,
+ LOGIN_UPD_REMOVE_ACCOUNT_FLAG,
LOGIN_SEL_PINFO,
LOGIN_SEL_PINFO_BANS,
LOGIN_SEL_GM_ACCOUNTS,
diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp
index daa82f804a..c4f0649c12 100644
--- a/src/server/game/Accounts/AccountMgr.cpp
+++ b/src/server/game/Accounts/AccountMgr.cpp
@@ -16,6 +16,7 @@
*/
#include "AccountMgr.h"
+#include "Common.h"
#include "DatabaseEnv.h"
#include "ObjectAccessor.h"
#include "Player.h"
@@ -298,6 +299,39 @@ namespace AccountMgr
return false;
}
+ bool HasAccountFlag(uint32 accountId, uint32 flag)
+ {
+ LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_FLAG);
+ stmt->SetData(0, accountId);
+ if (PreparedQueryResult result = LoginDatabase.Query(stmt))
+ {
+ uint32 flags = (*result)[0].Get<uint32>();
+ return (flags & flag) != 0;
+ }
+
+ return false;
+ }
+
+ void UpdateAccountFlag(uint32 accountId, uint32 flag, bool remove /*= false*/)
+ {
+ LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(
+ remove ? LOGIN_UPD_REMOVE_ACCOUNT_FLAG : LOGIN_UPD_ADD_ACCOUNT_FLAG
+ );
+ stmt->SetData(0, flag);
+ stmt->SetData(1, accountId);
+ LoginDatabase.Execute(stmt);
+ }
+
+ void ValidateAccountFlags(uint32 accountId, uint32 flags, uint32 security)
+ {
+ bool hasGMFlag = (flags & ACCOUNT_FLAG_GM) != 0;
+
+ if (IsGMAccount(security) && !hasGMFlag)
+ UpdateAccountFlag(accountId, ACCOUNT_FLAG_GM);
+ else if (hasGMFlag && !IsGMAccount(security))
+ UpdateAccountFlag(accountId, ACCOUNT_FLAG_GM, true);
+ }
+
uint32 GetCharactersCount(uint32 accountId)
{
// check character count
@@ -313,6 +347,11 @@ namespace AccountMgr
return gmlevel == SEC_PLAYER;
}
+ bool IsGMAccount(uint32 gmlevel)
+ {
+ return gmlevel >= SEC_GAMEMASTER;
+ }
+
bool IsAdminAccount(uint32 gmlevel)
{
return gmlevel >= SEC_ADMINISTRATOR && gmlevel <= SEC_CONSOLE;
diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h
index 57b6c7432a..d2fa715b5e 100644
--- a/src/server/game/Accounts/AccountMgr.h
+++ b/src/server/game/Accounts/AccountMgr.h
@@ -19,6 +19,7 @@
#define _ACCMGR_H
#include "Define.h"
+#include "Common.h"
#include <string>
enum AccountOpResult
@@ -52,8 +53,13 @@ namespace AccountMgr
uint32 GetCharactersCount(uint32 accountId);
bool IsPlayerAccount(uint32 gmlevel);
+ bool IsGMAccount(uint32 gmlevel);
bool IsAdminAccount(uint32 gmlevel);
bool IsConsoleAccount(uint32 gmlevel);
+
+ bool HasAccountFlag(uint32 accountId, uint32 flag);
+ void UpdateAccountFlag(uint32 accountId, uint32 flag, bool remove = false);
+ void ValidateAccountFlags(uint32 accountId, uint32 flags, uint32 security);
};
#endif
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index a745ecc65a..9c4d9de8e9 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -352,6 +352,7 @@ struct AccountInfo
bool IsLockedToIP;
std::string LockCountry;
uint8 Expansion;
+ uint32 Flags;
int64 MuteTime;
LocaleConstant Locale;
uint32 Recruiter;
@@ -363,9 +364,9 @@ struct AccountInfo
explicit AccountInfo(Field* fields)
{
- // 0 1 2 3 4 5 6 7 8 9 10 11
- // SELECT a.id, a.sessionkey, a.last_ip, a.locked, a.lock_country, a.expansion, a.mutetime, a.locale, a.recruiter, a.os, a.totaltime, aa.gmLevel,
- // 12 13
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12
+ // SELECT a.id, a.sessionkey, a.last_ip, a.locked, a.lock_country, a.expansion, a.Flags a.mutetime, a.locale, a.recruiter, a.os, a.totaltime, aa.gmLevel,
+ // 13 14
// ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, r.id
// FROM account a
// LEFT JOIN account_access aa ON a.id = aa.AccountID AND aa.RealmID IN (-1, ?)
@@ -378,14 +379,15 @@ struct AccountInfo
IsLockedToIP = fields[3].Get<bool>();
LockCountry = fields[4].Get<std::string>();
Expansion = fields[5].Get<uint8>();
- MuteTime = fields[6].Get<int64>();
- Locale = LocaleConstant(fields[7].Get<uint8>());
- Recruiter = fields[8].Get<uint32>();
- OS = fields[9].Get<std::string>();
- TotalTime = fields[10].Get<uint32>();
- Security = AccountTypes(fields[11].Get<uint8>());
- IsBanned = fields[12].Get<uint64>() != 0;
- IsRectuiter = fields[13].Get<uint32>() != 0;
+ Flags = fields[6].Get<uint32>();
+ MuteTime = fields[7].Get<int64>();
+ Locale = LocaleConstant(fields[8].Get<uint8>());
+ Recruiter = fields[9].Get<uint32>();
+ OS = fields[10].Get<std::string>();
+ TotalTime = fields[11].Get<uint32>();
+ Security = AccountTypes(fields[12].Get<uint8>());
+ IsBanned = fields[13].Get<uint64>() != 0;
+ IsRectuiter = fields[14].Get<uint32>() != 0;
uint32 world_expansion = sWorld->getIntConfig(CONFIG_EXPANSION);
if (Expansion > world_expansion)
@@ -696,6 +698,8 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<AuthSession> authSes
LoginDatabase.Execute(stmt);
+ AccountMgr::ValidateAccountFlags(account.Id, account.Flags, account.Security);
+
// At this point, we can safely hook a successful login
sScriptMgr->OnAccountLogin(account.Id);