mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 09:17:18 +00:00
feat(Core/RealmList): port TrinityCore realm api (#5626)
* feat(Core/RealmList): port TrinityCore realm api * 1 * whitespace cleanup * Update data/sql/updates/pending_db_auth/rev_1620114805872279900.sql Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> * 1 * 2 * Update data/sql/updates/pending_db_auth/rev_1620114805872279900.sql Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> * ` * 1 * small corrects * finish maybe * realm.Id.Realm * ws * 1 Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com>
This commit is contained in:
35
data/sql/updates/pending_db_auth/rev_1620114805872279900.sql
Normal file
35
data/sql/updates/pending_db_auth/rev_1620114805872279900.sql
Normal file
@@ -0,0 +1,35 @@
|
||||
INSERT INTO `version_db_auth` (`sql_rev`) VALUES ('1620114805872279900');
|
||||
|
||||
--
|
||||
-- Table structure for table `build_info`
|
||||
--
|
||||
DROP TABLE IF EXISTS `build_info`;
|
||||
CREATE TABLE `build_info` (
|
||||
`build` INT NOT NULL,
|
||||
`majorVersion` INT DEFAULT NULL,
|
||||
`minorVersion` INT DEFAULT NULL,
|
||||
`bugfixVersion` INT DEFAULT NULL,
|
||||
`hotfixVersion` CHAR(3) DEFAULT NULL,
|
||||
`winAuthSeed` VARCHAR(32) DEFAULT NULL,
|
||||
`win64AuthSeed` VARCHAR(32) DEFAULT NULL,
|
||||
`mac64AuthSeed` VARCHAR(32) DEFAULT NULL,
|
||||
`winChecksumSeed` VARCHAR(40) DEFAULT NULL,
|
||||
`macChecksumSeed` VARCHAR(40) DEFAULT NULL,
|
||||
PRIMARY KEY (`build`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- Dumping data for table `build_info`
|
||||
--
|
||||
INSERT INTO `build_info` VALUES
|
||||
(5875,1,12,1,NULL,NULL,NULL,NULL,'95EDB27C7823B363CBDDAB56A392E7CB73FCCA20','8D173CC381961EEBABF336F5E6675B101BB513E5'),
|
||||
(6005,1,12,2,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(6141,1,12,3,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(8606,2,4,3,NULL,NULL,NULL,NULL,'319AFAA3F2559682F9FF658BE01456255F456FB1','D8B0ECFE534BC1131E19BAD1D4C0E813EEE4994F'),
|
||||
(9947,3,1,3,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(10505,3,2,2,'a',NULL,NULL,NULL,NULL,NULL),
|
||||
(11159,3,3,0,'a',NULL,NULL,NULL,NULL,NULL),
|
||||
(11403,3,3,2,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(11723,3,3,3,'a',NULL,NULL,NULL,NULL,NULL),
|
||||
(12340,3,3,5,'a',NULL,NULL,NULL,'CDCBBD5188315E6B4D19449D492DBCFAF156A347','B706D13FF2F4018839729461E3F8A0E2B5FDC034'),
|
||||
(13930,3,3,5,'a',NULL,NULL,NULL,NULL,NULL);
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <utility>
|
||||
|
||||
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
|
||||
#include <ace/config-all.h>
|
||||
#include <ws2tcpip.h>
|
||||
#if AC_COMPILER == AC_COMPILER_INTEL
|
||||
# if !defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
@@ -5,66 +5,24 @@
|
||||
*/
|
||||
|
||||
#include "AuthCodes.h"
|
||||
#include <cstddef>
|
||||
#include "RealmList.h"
|
||||
|
||||
namespace AuthHelper
|
||||
{
|
||||
static RealmBuildInfo const PostBcAcceptedClientBuilds[] =
|
||||
{
|
||||
{15595, 4, 3, 4, ' '},
|
||||
{14545, 4, 2, 2, ' '},
|
||||
{13623, 4, 0, 6, 'a'},
|
||||
{12340, 3, 3, 5, 'a'},
|
||||
{11723, 3, 3, 3, 'a'},
|
||||
{11403, 3, 3, 2, ' '},
|
||||
{11159, 3, 3, 0, 'a'},
|
||||
{10505, 3, 2, 2, 'a'},
|
||||
{9947, 3, 1, 3, ' '},
|
||||
{8606, 2, 4, 3, ' '},
|
||||
{0, 0, 0, 0, ' '} // terminator
|
||||
};
|
||||
constexpr static uint32 MAX_PRE_BC_CLIENT_BUILD = 6141;
|
||||
|
||||
static RealmBuildInfo const PreBcAcceptedClientBuilds[] =
|
||||
bool IsPreBCAcceptedClientBuild(uint32 build)
|
||||
{
|
||||
{6141, 1, 12, 3, ' '},
|
||||
{6005, 1, 12, 2, ' '},
|
||||
{5875, 1, 12, 1, ' '},
|
||||
{0, 0, 0, 0, ' '} // terminator
|
||||
};
|
||||
|
||||
bool IsPreBCAcceptedClientBuild(int build)
|
||||
{
|
||||
for (int i = 0; PreBcAcceptedClientBuilds[i].Build; ++i)
|
||||
if (PreBcAcceptedClientBuilds[i].Build == build)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return build <= MAX_PRE_BC_CLIENT_BUILD && sRealmList->GetBuildInfo(build);
|
||||
}
|
||||
|
||||
bool IsPostBCAcceptedClientBuild(int build)
|
||||
bool IsPostBCAcceptedClientBuild(uint32 build)
|
||||
{
|
||||
for (int i = 0; PostBcAcceptedClientBuilds[i].Build; ++i)
|
||||
if (PostBcAcceptedClientBuilds[i].Build == build)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return build > MAX_PRE_BC_CLIENT_BUILD && sRealmList->GetBuildInfo(build);
|
||||
}
|
||||
|
||||
bool IsAcceptedClientBuild(int build)
|
||||
bool IsAcceptedClientBuild(uint32 build)
|
||||
{
|
||||
return (IsPostBCAcceptedClientBuild(build) || IsPreBCAcceptedClientBuild(build));
|
||||
}
|
||||
|
||||
RealmBuildInfo const* GetBuildInfo(int build)
|
||||
{
|
||||
for (int i = 0; PostBcAcceptedClientBuilds[i].Build; ++i)
|
||||
if (PostBcAcceptedClientBuilds[i].Build == build)
|
||||
return &PostBcAcceptedClientBuilds[i];
|
||||
|
||||
for (int i = 0; PreBcAcceptedClientBuilds[i].Build; ++i)
|
||||
if (PreBcAcceptedClientBuilds[i].Build == build)
|
||||
return &PreBcAcceptedClientBuilds[i];
|
||||
|
||||
return nullptr;
|
||||
return sRealmList->GetBuildInfo(build) != nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
#ifndef _AUTHCODES_H
|
||||
#define _AUTHCODES_H
|
||||
|
||||
#include "Define.h"
|
||||
#include <array>
|
||||
|
||||
enum AuthResult
|
||||
{
|
||||
WOW_SUCCESS = 0x00,
|
||||
@@ -65,21 +68,13 @@ enum ExpansionFlags
|
||||
NO_VALID_EXP_FLAG = 0x0
|
||||
};
|
||||
|
||||
struct RealmBuildInfo
|
||||
{
|
||||
int Build;
|
||||
int MajorVersion;
|
||||
int MinorVersion;
|
||||
int BugfixVersion;
|
||||
int HotfixVersion;
|
||||
};
|
||||
struct RealmBuildInfo;
|
||||
|
||||
namespace AuthHelper
|
||||
{
|
||||
RealmBuildInfo const* GetBuildInfo(int build);
|
||||
bool IsAcceptedClientBuild(int build);
|
||||
bool IsPostBCAcceptedClientBuild(int build);
|
||||
bool IsPreBCAcceptedClientBuild(int build);
|
||||
bool IsAcceptedClientBuild(uint32 build);
|
||||
bool IsPostBCAcceptedClientBuild(uint32 build);
|
||||
bool IsPreBCAcceptedClientBuild(uint32 build);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -135,7 +135,7 @@ extern int main(int argc, char** argv)
|
||||
|
||||
// Get the list of realms for the server
|
||||
sRealmList->Initialize(sConfigMgr->GetOption<int32>("RealmsStateUpdateDelay", 20));
|
||||
if (sRealmList->size() == 0)
|
||||
if (sRealmList->GetRealms().empty())
|
||||
{
|
||||
LOG_ERROR("server.authserver", "No valid realms specified.");
|
||||
return 1;
|
||||
|
||||
@@ -165,6 +165,8 @@ private:
|
||||
Patches _patches;
|
||||
};
|
||||
|
||||
std::array<uint8, 16> VersionChallenge = { { 0xBA, 0xA3, 0x1E, 0x99, 0xA0, 0x0B, 0x21, 0x57, 0xFC, 0x37, 0x3F, 0xB3, 0x69, 0xCD, 0xD2, 0xF1 } };
|
||||
|
||||
const AuthHandler table[] =
|
||||
{
|
||||
{ AUTH_LOGON_CHALLENGE, STATUS_CHALLENGE, &AuthSocket::_HandleLogonChallenge },
|
||||
@@ -366,6 +368,10 @@ bool AuthSocket::_HandleLogonChallenge()
|
||||
// Restore string order as its byte order is reversed
|
||||
std::reverse(_os.begin(), _os.end());
|
||||
|
||||
_localizationName.resize(4);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
_localizationName[i] = ch->country[4 - i - 1];
|
||||
|
||||
ByteBuffer pkt;
|
||||
pkt << uint8(AUTH_LOGON_CHALLENGE);
|
||||
pkt << uint8(0x00);
|
||||
@@ -487,9 +493,6 @@ bool AuthSocket::_HandleLogonChallenge()
|
||||
fields[10].GetBinary<acore::Crypto::SRP6::SALT_LENGTH>(),
|
||||
fields[11].GetBinary<acore::Crypto::SRP6::VERIFIER_LENGTH>());
|
||||
|
||||
BigNumber unk3;
|
||||
unk3.SetRand(16 * 8);
|
||||
|
||||
// Fill the response packet with the result
|
||||
if (!AuthHelper::IsAcceptedClientBuild(_build))
|
||||
{
|
||||
@@ -507,8 +510,7 @@ bool AuthSocket::_HandleLogonChallenge()
|
||||
pkt << uint8(32);
|
||||
pkt.append(_srp6->N);
|
||||
pkt.append(_srp6->s);
|
||||
pkt.append(unk3.ToByteArray<16>());
|
||||
|
||||
pkt.append(VersionChallenge.data(), VersionChallenge.size());
|
||||
pkt << uint8(securityFlags); // security flags (0x0...0x04)
|
||||
|
||||
if (securityFlags & 0x01) // PIN input
|
||||
@@ -529,11 +531,7 @@ bool AuthSocket::_HandleLogonChallenge()
|
||||
if (securityFlags & 0x04) // Security token input
|
||||
pkt << uint8(1);
|
||||
|
||||
_localizationName.resize(4);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
_localizationName[i] = ch->country[4 - i - 1];
|
||||
|
||||
LOG_DEBUG("network", "'%s:%d' [AuthChallenge] account %s is using locale (%u)",
|
||||
LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] account %s is using locale (%u)",
|
||||
ipAddress.c_str(), port, _accountInfo.Login.c_str(), GetLocaleByName(_localizationName));
|
||||
|
||||
///- All good, await client's proof
|
||||
@@ -546,9 +544,8 @@ bool AuthSocket::_HandleLogonChallenge()
|
||||
// Logon Proof command handler
|
||||
bool AuthSocket::_HandleLogonProof()
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("network", "Entering _HandleLogonProof");
|
||||
#endif
|
||||
LOG_TRACE("server.authserver", "Entering _HandleLogonProof");
|
||||
|
||||
// Read the packet
|
||||
sAuthLogonProof_C lp;
|
||||
|
||||
@@ -571,20 +568,6 @@ bool AuthSocket::_HandleLogonProof()
|
||||
if (std::optional<SessionKey> K = _srp6->VerifyChallengeResponse(lp.A, lp.clientM))
|
||||
{
|
||||
_sessionKey = *K;
|
||||
LOG_DEBUG("network", "'%s:%d' User '%s' successfully authenticated", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str());
|
||||
|
||||
// Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account
|
||||
// No SQL injection (escaped user name) and IP address as received by socket
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LOGONPROOF);
|
||||
stmt->setBinary(0, _sessionKey);
|
||||
stmt->setString(1, socket().getRemoteAddress().c_str());
|
||||
stmt->setUInt32(2, GetLocaleByName(_localizationName));
|
||||
stmt->setString(3, _os);
|
||||
stmt->setString(4, _accountInfo.Login);
|
||||
LoginDatabase.DirectExecute(stmt);
|
||||
|
||||
// Finish SRP6 and send the final result to the client
|
||||
acore::Crypto::SHA1::Digest M2 = acore::Crypto::SRP6::GetSessionVerifier(lp.A, lp.clientM, _sessionKey);
|
||||
|
||||
// Check auth token
|
||||
bool tokenSuccess = false;
|
||||
@@ -613,6 +596,21 @@ bool AuthSocket::_HandleLogonProof()
|
||||
socket().send(data, sizeof(data));
|
||||
}
|
||||
|
||||
LOG_DEBUG("network", "'%s:%d' User '%s' successfully authenticated", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str());
|
||||
|
||||
// Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account
|
||||
// No SQL injection (escaped user name) and IP address as received by socket
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LOGONPROOF);
|
||||
stmt->setBinary(0, _sessionKey);
|
||||
stmt->setString(1, socket().getRemoteAddress().c_str());
|
||||
stmt->setUInt32(2, GetLocaleByName(_localizationName));
|
||||
stmt->setString(3, _os);
|
||||
stmt->setString(4, _accountInfo.Login);
|
||||
LoginDatabase.DirectExecute(stmt);
|
||||
|
||||
// Finish SRP6 and send the final result to the client
|
||||
acore::Crypto::SHA1::Digest M2 = acore::Crypto::SRP6::GetSessionVerifier(lp.A, lp.clientM, _sessionKey);
|
||||
|
||||
if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients
|
||||
{
|
||||
sAuthLogonProof_S proof;
|
||||
@@ -621,7 +619,7 @@ bool AuthSocket::_HandleLogonProof()
|
||||
proof.error = 0;
|
||||
proof.unk1 = 0x00800000; // Accountflags. 0x01 = GM, 0x08 = Trial, 0x00800000 = Pro pass (arena tournament)
|
||||
proof.unk2 = 0x00; // SurveyId
|
||||
proof.unk3 = 0x00;
|
||||
proof.unk3 = 0x00; // 0x1 = has account message
|
||||
socket().send((char*)&proof, sizeof(proof));
|
||||
}
|
||||
else
|
||||
@@ -642,9 +640,8 @@ bool AuthSocket::_HandleLogonProof()
|
||||
char data[4] = { AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0 };
|
||||
socket().send(data, sizeof(data));
|
||||
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("network", "'%s:%d' [AuthChallenge] account %s tried to login with invalid password!", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str());
|
||||
#endif
|
||||
LOG_INFO("server.authserver.hack", "'%s:%d' [AuthChallenge] account %s tried to login with invalid password!",
|
||||
socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str());
|
||||
|
||||
uint32 MaxWrongPassCount = sConfigMgr->GetOption<int32>("WrongPass.MaxCount", 0);
|
||||
|
||||
@@ -666,42 +663,30 @@ bool AuthSocket::_HandleLogonProof()
|
||||
stmt->setString(0, _accountInfo.Login);
|
||||
LoginDatabase.Execute(stmt);
|
||||
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_FAILEDLOGINS);
|
||||
stmt->setString(0, _accountInfo.Login);
|
||||
|
||||
if (PreparedQueryResult loginfail = LoginDatabase.Query(stmt))
|
||||
if (++_accountInfo.FailedLogins >= MaxWrongPassCount)
|
||||
{
|
||||
uint32 failed_logins = (*loginfail)[1].GetUInt32();
|
||||
uint32 WrongPassBanTime = sConfigMgr->GetOption<int32>("WrongPass.BanTime", 600);
|
||||
bool WrongPassBanType = sConfigMgr->GetOption<bool>("WrongPass.BanType", false);
|
||||
|
||||
if (failed_logins >= MaxWrongPassCount)
|
||||
if (WrongPassBanType)
|
||||
{
|
||||
uint32 WrongPassBanTime = sConfigMgr->GetOption<int32>("WrongPass.BanTime", 600);
|
||||
bool WrongPassBanType = sConfigMgr->GetOption<bool>("WrongPass.BanType", false);
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_AUTO_BANNED);
|
||||
stmt->setUInt32(0, _accountInfo.Id);
|
||||
stmt->setUInt32(1, WrongPassBanTime);
|
||||
LoginDatabase.Execute(stmt);
|
||||
|
||||
if (WrongPassBanType)
|
||||
{
|
||||
uint32 acc_id = (*loginfail)[0].GetUInt32();
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_AUTO_BANNED);
|
||||
stmt->setUInt32(0, acc_id);
|
||||
stmt->setUInt32(1, WrongPassBanTime);
|
||||
LoginDatabase.Execute(stmt);
|
||||
LOG_DEBUG("network", "'%s:%d' [AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times",
|
||||
socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str(), WrongPassBanTime, _accountInfo.FailedLogins);
|
||||
}
|
||||
else
|
||||
{
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_IP_AUTO_BANNED);
|
||||
stmt->setString(0, socket().getRemoteAddress());
|
||||
stmt->setUInt32(1, WrongPassBanTime);
|
||||
LoginDatabase.Execute(stmt);
|
||||
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("network", "'%s:%d' [AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str(), WrongPassBanTime, failed_logins);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_IP_AUTO_BANNED);
|
||||
stmt->setString(0, socket().getRemoteAddress());
|
||||
stmt->setUInt32(1, WrongPassBanTime);
|
||||
LoginDatabase.Execute(stmt);
|
||||
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("network", "'%s:%d' [AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times",
|
||||
socket().getRemoteAddress().c_str(), socket().getRemotePort(), socket().getRemoteAddress().c_str(), WrongPassBanTime, _accountInfo.Login.c_str(), failed_logins);
|
||||
#endif
|
||||
}
|
||||
LOG_DEBUG("network", "'%s:%d' [AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times",
|
||||
socket().getRemoteAddress().c_str(), socket().getRemotePort(), socket().getRemoteAddress().c_str(), WrongPassBanTime, _accountInfo.Login.c_str(), _accountInfo.FailedLogins);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -713,9 +698,8 @@ bool AuthSocket::_HandleLogonProof()
|
||||
// Reconnect Challenge command handler
|
||||
bool AuthSocket::_HandleReconnectChallenge()
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("network", "Entering _HandleReconnectChallenge");
|
||||
#endif
|
||||
LOG_TRACE("network", "Entering _HandleReconnectChallenge");
|
||||
|
||||
if (socket().recv_len() < sizeof(sAuthLogonChallenge_C))
|
||||
return false;
|
||||
|
||||
@@ -751,6 +735,15 @@ bool AuthSocket::_HandleReconnectChallenge()
|
||||
#endif
|
||||
|
||||
std::string login((char const*)ch->I, ch->I_len);
|
||||
LOG_DEBUG("server.authserver", "[ReconnectChallenge] '%s'", login.c_str());
|
||||
|
||||
// Reinitialize build, expansion and the account securitylevel
|
||||
_build = ch->build;
|
||||
_expversion = uint8(AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG));
|
||||
_os = (const char*)ch->os;
|
||||
|
||||
if (_os.size() > 4)
|
||||
return false;
|
||||
|
||||
auto* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RECONNECTCHALLENGE);
|
||||
stmt->setString(0, login);
|
||||
@@ -768,14 +761,6 @@ bool AuthSocket::_HandleReconnectChallenge()
|
||||
Field* fields = result->Fetch();
|
||||
_accountInfo.LoadResult(fields);
|
||||
|
||||
// Reinitialize build, expansion and the account securitylevel
|
||||
_build = ch->build;
|
||||
_expversion = uint8(AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG));
|
||||
_os = (const char*)ch->os;
|
||||
|
||||
if (_os.size() > 4)
|
||||
return false;
|
||||
|
||||
// Restore string order as its byte order is reversed
|
||||
std::reverse(_os.begin(), _os.end());
|
||||
|
||||
@@ -788,9 +773,9 @@ bool AuthSocket::_HandleReconnectChallenge()
|
||||
// Sending response
|
||||
ByteBuffer pkt;
|
||||
pkt << uint8(AUTH_RECONNECT_CHALLENGE);
|
||||
pkt << uint8(0x00);
|
||||
pkt << uint8(WOW_SUCCESS);
|
||||
pkt.append(_reconnectProof); // 16 bytes random
|
||||
pkt << uint64(0x00) << uint64(0x00); // 16 bytes zeros
|
||||
pkt.append(VersionChallenge.data(), VersionChallenge.size());
|
||||
socket().send((char const*)pkt.contents(), pkt.size());
|
||||
return true;
|
||||
}
|
||||
@@ -837,7 +822,8 @@ bool AuthSocket::_HandleReconnectProof()
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("server", "'%s:%d' [ERROR] user %s tried to login, but session is invalid.", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str());
|
||||
LOG_ERROR("server.authserver.hack", "'%s:%d' [ERROR] user %s tried to login, but session is invalid.",
|
||||
socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str());
|
||||
socket().shutdown();
|
||||
return false;
|
||||
}
|
||||
@@ -849,20 +835,22 @@ ACE_INET_Addr const& AuthSocket::GetAddressForClient(Realm const& realm, ACE_INE
|
||||
if (clientAddr.is_loopback())
|
||||
{
|
||||
// Try guessing if realm is also connected locally
|
||||
if (realm.LocalAddress.is_loopback() || realm.ExternalAddress.is_loopback())
|
||||
if (realm.LocalAddress->is_loopback() || realm.ExternalAddress->is_loopback())
|
||||
return clientAddr;
|
||||
|
||||
// Assume that user connecting from the machine that authserver is located on
|
||||
// has all realms available in his local network
|
||||
return realm.LocalAddress;
|
||||
return *realm.LocalAddress;
|
||||
}
|
||||
|
||||
// Check if connecting client is in the same network
|
||||
if (IsIPAddrInNetwork(realm.LocalAddress, clientAddr, realm.LocalSubnetMask))
|
||||
return realm.LocalAddress;
|
||||
if (IsIPAddrInNetwork(*realm.LocalAddress, clientAddr, *realm.LocalSubnetMask))
|
||||
{
|
||||
return *realm.LocalAddress;
|
||||
}
|
||||
|
||||
// Return external IP
|
||||
return realm.ExternalAddress;
|
||||
return *realm.ExternalAddress;
|
||||
}
|
||||
|
||||
// Realm List command handler
|
||||
@@ -900,17 +888,17 @@ bool AuthSocket::_HandleRealmList()
|
||||
|
||||
// Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm)
|
||||
ByteBuffer pkt;
|
||||
|
||||
size_t RealmListSize = 0;
|
||||
for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i)
|
||||
|
||||
for (auto& [realmHandle, realm] : sRealmList->GetRealms())
|
||||
{
|
||||
const Realm& realm = i->second;
|
||||
// don't work with realms which not compatible with the client
|
||||
bool okBuild = ((_expversion & POST_BC_EXP_FLAG) && realm.gamebuild == _build) || ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(realm.gamebuild));
|
||||
bool okBuild = ((_expversion & POST_BC_EXP_FLAG) && realm.Build == _build) || ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(realm.Build));
|
||||
|
||||
// No SQL injection. id of realm is controlled by the database.
|
||||
uint32 flag = realm.flag;
|
||||
RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.gamebuild);
|
||||
uint32 flag = realm.Flags;
|
||||
|
||||
RealmBuildInfo const* buildInfo = sRealmList->GetBuildInfo(realm.Build);
|
||||
if (!okBuild)
|
||||
{
|
||||
if (!buildInfo)
|
||||
@@ -922,7 +910,7 @@ bool AuthSocket::_HandleRealmList()
|
||||
if (!buildInfo)
|
||||
flag &= ~REALM_FLAG_SPECIFYBUILD;
|
||||
|
||||
std::string name = i->first;
|
||||
std::string name = realm.Name;
|
||||
if (_expversion & PRE_BC_EXP_FLAG && flag & REALM_FLAG_SPECIFYBUILD)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
@@ -931,29 +919,29 @@ bool AuthSocket::_HandleRealmList()
|
||||
}
|
||||
|
||||
// We don't need the port number from which client connects with but the realm's port
|
||||
clientAddr.set_port_number(realm.ExternalAddress.get_port_number());
|
||||
clientAddr.set_port_number(realm.ExternalAddress->get_port_number());
|
||||
|
||||
uint8 lock = (realm.allowedSecurityLevel > _accountInfo.SecurityLevel) ? 1 : 0;
|
||||
uint8 lock = (realm.AllowedSecurityLevel > _accountInfo.SecurityLevel) ? 1 : 0;
|
||||
|
||||
uint8 AmountOfCharacters = 0;
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_NUM_CHARS_ON_REALM);
|
||||
stmt->setUInt32(0, realm.m_ID);
|
||||
stmt->setUInt32(0, realm.Id.Realm);
|
||||
stmt->setUInt32(1, id);
|
||||
result = LoginDatabase.Query(stmt);
|
||||
if (result)
|
||||
AmountOfCharacters = (*result)[0].GetUInt8();
|
||||
|
||||
pkt << realm.icon; // realm type
|
||||
pkt << realm.Type; // realm type
|
||||
if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients
|
||||
pkt << lock; // if 1, then realm locked
|
||||
pkt << uint8(flag); // RealmFlags
|
||||
pkt << name;
|
||||
pkt << GetAddressString(GetAddressForClient(realm, clientAddr));
|
||||
pkt << realm.populationLevel;
|
||||
pkt << realm.PopulationLevel;
|
||||
pkt << AmountOfCharacters;
|
||||
pkt << realm.timezone; // realm category
|
||||
pkt << realm.Timezone; // realm category
|
||||
if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients
|
||||
pkt << uint8(realm.m_ID);
|
||||
pkt << uint8(realm.Id.Realm);
|
||||
else
|
||||
pkt << uint8(0x0); // 1.12.1 and 1.12.2 clients
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Player.h"
|
||||
#include "Realm.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "UpdateMask.h"
|
||||
@@ -114,7 +115,7 @@ bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_ac
|
||||
if (target)
|
||||
target_sec = target->GetSecurity();
|
||||
else if (target_account)
|
||||
target_sec = AccountMgr::GetSecurity(target_account, realmID);
|
||||
target_sec = AccountMgr::GetSecurity(target_account, realm.Id.Realm);
|
||||
else
|
||||
return true; // caller must report error for (target == nullptr && target_account == 0)
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "QuestDef.h"
|
||||
#include "ReputationMgr.h"
|
||||
#include "revision.h"
|
||||
#include "Realm.h"
|
||||
#include "SavingSystem.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SkillDiscovery.h"
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "Pet.h"
|
||||
#include "Player.h"
|
||||
#include "PlayerDump.h"
|
||||
#include "Realm.h"
|
||||
#include "ReputationMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ServerMotd.h"
|
||||
@@ -647,13 +648,13 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
|
||||
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM);
|
||||
stmt->setUInt32(0, GetAccountId());
|
||||
stmt->setUInt32(1, realmID);
|
||||
stmt->setUInt32(1, realm.Id.Realm);
|
||||
trans->Append(stmt);
|
||||
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS);
|
||||
stmt->setUInt32(0, createInfo->CharCount);
|
||||
stmt->setUInt32(1, GetAccountId());
|
||||
stmt->setUInt32(2, realmID);
|
||||
stmt->setUInt32(2, realm.Id.Realm);
|
||||
trans->Append(stmt);
|
||||
|
||||
LoginDatabase.CommitTransaction(trans);
|
||||
@@ -996,7 +997,7 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder* holder)
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_ONLINE);
|
||||
stmt->setUInt32(0, realmID);
|
||||
stmt->setUInt32(0, realm.Id.Realm);
|
||||
stmt->setUInt32(1, GetAccountId());
|
||||
LoginDatabase.Execute(stmt);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "Realm.h"
|
||||
#include "SocialMgr.h"
|
||||
#include "World.h"
|
||||
#include "WorldSession.h"
|
||||
@@ -52,7 +53,7 @@ void WorldSession::HandleAddFriendOpcode(WorldPacket& recv_data)
|
||||
TeamId teamId = Player::TeamIdForRace(playerData->race);
|
||||
FriendsResult friendResult = FRIEND_NOT_FOUND;
|
||||
|
||||
if (!AccountMgr::IsPlayerAccount(GetSecurity()) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND)|| AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID)))
|
||||
if (!AccountMgr::IsPlayerAccount(GetSecurity()) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND)|| AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realm.Id.Realm)))
|
||||
{
|
||||
if (friendGuid)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "Opcodes.h"
|
||||
#include "PacketLog.h"
|
||||
#include "Player.h"
|
||||
#include "Realm.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "Util.h"
|
||||
@@ -791,7 +792,7 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
|
||||
int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
|
||||
{
|
||||
// NOTE: ATM the socket is singlethread, have this in mind ...
|
||||
uint32 loginServerID, loginServerType, regionID, battlegroupID, realm;
|
||||
uint32 loginServerID, loginServerType, regionID, battlegroupID, realmid;
|
||||
uint64 DosResponse;
|
||||
uint32 BuiltNumberClient;
|
||||
std::string accountName;
|
||||
@@ -817,7 +818,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
|
||||
recvPacket.read(clientSeed);
|
||||
recvPacket >> regionID;
|
||||
recvPacket >> battlegroupID;
|
||||
recvPacket >> realm;
|
||||
recvPacket >> realmid;
|
||||
recvPacket >> DosResponse;
|
||||
recvPacket.read(digest);
|
||||
|
||||
@@ -829,7 +830,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
|
||||
// 0 1 2 3 4 5 6 7 8 9 10
|
||||
// SELECT id, sessionkey, last_ip, locked, lock_country, expansion, mutetime, locale, recruiter, os, totaltime FROM account WHERE username = ?
|
||||
auto* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME);
|
||||
stmt->setInt32(0, int32(realmID));
|
||||
stmt->setInt32(0, int32(realm.Id.Realm));
|
||||
stmt->setString(1, accountName);
|
||||
|
||||
PreparedQueryResult result = LoginDatabase.Query(stmt);
|
||||
@@ -856,11 +857,10 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LAST_ATTEMPT_IP);
|
||||
stmt->setString(0, address);
|
||||
stmt->setString(1, accountName);
|
||||
|
||||
LoginDatabase.Execute(stmt);
|
||||
// This also allows to check for possible "hack" attempts on account
|
||||
|
||||
// even if auth credentials are bad, try using the session key we have - client cannot read auth response error without it
|
||||
// even if auth credentials are bad, try using the session key we have - client cannot read auth response error without it
|
||||
m_Crypt.Init(account.SessionKey);
|
||||
|
||||
// First reject the connection if packet contains invalid data or realm state doesn't allow logging in
|
||||
@@ -875,14 +875,14 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (realm != realmID)
|
||||
if (realmid != realm.Id.Realm)
|
||||
{
|
||||
packet.Initialize(SMSG_AUTH_RESPONSE, 1);
|
||||
packet << uint8(REALM_LIST_REALM_NOT_FOUND);
|
||||
SendPacket(packet);
|
||||
|
||||
LOG_ERROR("server", "WorldSocket::HandleAuthSession: Client %s requested connecting with realm id %u but this realm has id %u set in config.",
|
||||
address.c_str(), realm, realmID);
|
||||
address.c_str(), realmid, realm.Id.Realm);
|
||||
sScriptMgr->OnFailedAccountLogin(account.Id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "PetitionMgr.h"
|
||||
#include "Player.h"
|
||||
#include "PoolMgr.h"
|
||||
#include "Realm.h"
|
||||
#include "SavingSystem.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ServerMotd.h"
|
||||
@@ -91,6 +92,8 @@ float World::m_MaxVisibleDistanceOnContinents = DEFAULT_VISIBILITY_DISTANCE;
|
||||
float World::m_MaxVisibleDistanceInInstances = DEFAULT_VISIBILITY_INSTANCE;
|
||||
float World::m_MaxVisibleDistanceInBGArenas = DEFAULT_VISIBILITY_BGARENAS;
|
||||
|
||||
Realm realm;
|
||||
|
||||
/// World constructor
|
||||
World::World()
|
||||
{
|
||||
@@ -428,7 +431,7 @@ void World::LoadConfigSettings(bool reload)
|
||||
}
|
||||
|
||||
// Set realm id and enable db logging
|
||||
sLog->SetRealmId(realmID);
|
||||
sLog->SetRealmId(realm.Id.Realm);
|
||||
|
||||
#ifdef ELUNA
|
||||
///- Initialize Lua Engine
|
||||
@@ -1488,7 +1491,7 @@ void World::SetInitialWorldSettings()
|
||||
|
||||
uint32 realm_zone = getIntConfig(CONFIG_REALM_ZONE);
|
||||
|
||||
LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmID); // One-time query
|
||||
LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realm.Id.Realm); // One-time query
|
||||
|
||||
///- Custom Hook for loading DB items
|
||||
sScriptMgr->OnLoadCustomDatabaseTable();
|
||||
@@ -1938,7 +1941,7 @@ void World::SetInitialWorldSettings()
|
||||
m_startTime = m_gameTime;
|
||||
|
||||
LoginDatabase.PExecute("INSERT INTO uptime (realmid, starttime, uptime, revision) VALUES(%u, %u, 0, '%s')",
|
||||
realmID, uint32(m_startTime), GitRevision::GetFullVersion()); // One-time query
|
||||
realm.Id.Realm, uint32(m_startTime), GitRevision::GetFullVersion()); // One-time query
|
||||
|
||||
m_timers[WUPDATE_WEATHERS].SetInterval(1 * IN_MILLISECONDS);
|
||||
m_timers[WUPDATE_AUCTIONS].SetInterval(MINUTE * IN_MILLISECONDS);
|
||||
@@ -2316,7 +2319,7 @@ void World::Update(uint32 diff)
|
||||
|
||||
stmt->setUInt32(0, tmpDiff);
|
||||
stmt->setUInt16(1, uint16(maxOnlinePlayers));
|
||||
stmt->setUInt32(2, realmID);
|
||||
stmt->setUInt32(2, realm.Id.Realm);
|
||||
stmt->setUInt32(3, uint32(m_startTime));
|
||||
|
||||
LoginDatabase.Execute(stmt);
|
||||
@@ -2854,13 +2857,13 @@ void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount)
|
||||
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM);
|
||||
stmt->setUInt32(0, accountId);
|
||||
stmt->setUInt32(1, realmID);
|
||||
stmt->setUInt32(1, realm.Id.Realm);
|
||||
trans->Append(stmt);
|
||||
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS);
|
||||
stmt->setUInt8(0, charCount);
|
||||
stmt->setUInt32(1, accountId);
|
||||
stmt->setUInt32(2, realmID);
|
||||
stmt->setUInt32(2, realm.Id.Realm);
|
||||
trans->Append(stmt);
|
||||
|
||||
LoginDatabase.CommitTransaction(trans);
|
||||
@@ -2988,7 +2991,7 @@ void World::ResetDailyQuests()
|
||||
void World::LoadDBAllowedSecurityLevel()
|
||||
{
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL);
|
||||
stmt->setInt32(0, int32(realmID));
|
||||
stmt->setInt32(0, int32(realm.Id.Realm));
|
||||
PreparedQueryResult result = LoginDatabase.Query(stmt);
|
||||
|
||||
if (result)
|
||||
@@ -3451,3 +3454,13 @@ void World::RemoveOldCorpses()
|
||||
{
|
||||
m_timers[WUPDATE_CORPSES].SetCurrent(m_timers[WUPDATE_CORPSES].GetInterval());
|
||||
}
|
||||
|
||||
bool World::IsPvPRealm() const
|
||||
{
|
||||
return getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP || getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP;
|
||||
}
|
||||
|
||||
bool World::IsFFAPvPRealm() const
|
||||
{
|
||||
return getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,9 @@ class WorldPacket;
|
||||
class WorldSocket;
|
||||
class SystemMgr;
|
||||
|
||||
extern uint32 realmID;
|
||||
struct Realm;
|
||||
|
||||
AC_GAME_API extern Realm realm;
|
||||
|
||||
enum ShutdownMask
|
||||
{
|
||||
@@ -74,18 +76,6 @@ enum BillingPlanFlags
|
||||
SESSION_ENABLE_CAIS = 0x80,
|
||||
};
|
||||
|
||||
/// Type of server, this is values from second column of Cfg_Configs.dbc
|
||||
enum RealmType
|
||||
{
|
||||
REALM_TYPE_NORMAL = 0,
|
||||
REALM_TYPE_PVP = 1,
|
||||
REALM_TYPE_NORMAL2 = 4,
|
||||
REALM_TYPE_RP = 6,
|
||||
REALM_TYPE_RPPVP = 8,
|
||||
REALM_TYPE_FFA_PVP = 16 // custom, free for all pvp mode like arena PvP in all zones except rest activated places and sanctuaries
|
||||
// replaced by REALM_PVP in realm list
|
||||
};
|
||||
|
||||
enum RealmZone
|
||||
{
|
||||
REALM_ZONE_UNKNOWN = 0, // any language
|
||||
@@ -335,8 +325,8 @@ public:
|
||||
void LoadWorldStates();
|
||||
|
||||
/// Are we on a "Player versus Player" server?
|
||||
bool IsPvPRealm() const { return (getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP || getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP); }
|
||||
bool IsFFAPvPRealm() const { return getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP; }
|
||||
[[nodiscard]] bool IsPvPRealm() const;
|
||||
[[nodiscard]] bool IsFFAPvPRealm() const;
|
||||
|
||||
void KickAll();
|
||||
void KickAllLess(AccountTypes sec);
|
||||
|
||||
@@ -18,6 +18,7 @@ EndScriptData */
|
||||
#include "CryptoGenerics.h"
|
||||
#include "Language.h"
|
||||
#include "Player.h"
|
||||
#include "Realm.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SecretMgr.h"
|
||||
#include "StringConvert.h"
|
||||
@@ -796,7 +797,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Check if provided realmID has a negative value other than -1
|
||||
// Check if provided realm.Id.Realm has a negative value other than -1
|
||||
if (gmRealmID < -1)
|
||||
{
|
||||
handler->SendSysMessage(LANG_INVALID_REALMID);
|
||||
@@ -804,7 +805,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
// If gmRealmID is -1, delete all values for the account id, else, insert values for the specific realmID
|
||||
// If gmRealmID is -1, delete all values for the account id, else, insert values for the specific realm.Id.Realm
|
||||
PreparedStatement* stmt;
|
||||
|
||||
if (gmRealmID == -1)
|
||||
@@ -818,7 +819,7 @@ public:
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM);
|
||||
|
||||
stmt->setUInt32(0, targetAccountId);
|
||||
stmt->setUInt32(1, realmID);
|
||||
stmt->setUInt32(1, realm.Id.Realm);
|
||||
}
|
||||
|
||||
LoginDatabase.Execute(stmt);
|
||||
|
||||
@@ -17,6 +17,7 @@ EndScriptData */
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Player.h"
|
||||
#include "Realm.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "World.h"
|
||||
|
||||
@@ -156,7 +157,7 @@ public:
|
||||
///- Get the accounts with GM Level >0
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_GM_ACCOUNTS);
|
||||
stmt->setUInt8(0, uint8(SEC_MODERATOR));
|
||||
stmt->setInt32(1, int32(realmID));
|
||||
stmt->setInt32(1, int32(realm.Id.Realm));
|
||||
PreparedQueryResult result = LoginDatabase.Query(stmt);
|
||||
|
||||
if (result)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "Opcodes.h"
|
||||
#include "Pet.h"
|
||||
#include "Player.h"
|
||||
#include "Realm.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "TargetedMovementGenerator.h"
|
||||
@@ -1909,7 +1910,7 @@ public:
|
||||
|
||||
// Query the prepared statement for login data
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO);
|
||||
stmt->setInt32(0, int32(realmID));
|
||||
stmt->setInt32(0, int32(realm.Id.Realm));
|
||||
stmt->setUInt32(1, accId);
|
||||
PreparedQueryResult accInfoResult = LoginDatabase.Query(stmt);
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ EndScriptData */
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Player.h"
|
||||
#include "Realm.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "TicketMgr.h"
|
||||
|
||||
@@ -84,7 +85,7 @@ public:
|
||||
// Get target information
|
||||
ObjectGuid targetGuid = sObjectMgr->GetPlayerGUIDByName(target.c_str());
|
||||
uint32 targetAccountId = sObjectMgr->GetPlayerAccountIdByGUID(targetGuid.GetCounter());
|
||||
uint32 targetGmLevel = AccountMgr::GetSecurity(targetAccountId, realmID);
|
||||
uint32 targetGmLevel = AccountMgr::GetSecurity(targetAccountId, realm.Id.Realm);
|
||||
|
||||
// Target must exist and have administrative rights
|
||||
if (!targetGuid || AccountMgr::IsPlayerAccount(targetGmLevel))
|
||||
@@ -382,7 +383,7 @@ public:
|
||||
{
|
||||
ObjectGuid guid = ticket->GetAssignedToGUID();
|
||||
uint32 accountId = sObjectMgr->GetPlayerAccountIdByGUID(guid.GetCounter());
|
||||
security = AccountMgr::GetSecurity(accountId, realmID);
|
||||
security = AccountMgr::GetSecurity(accountId, realm.Id.Realm);
|
||||
}
|
||||
|
||||
// Check security
|
||||
|
||||
73
src/server/shared/Realms/Realm.h
Normal file
73
src/server/shared/Realms/Realm.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
*/
|
||||
|
||||
#ifndef Realm_h__
|
||||
#define Realm_h__
|
||||
|
||||
#include "Common.h"
|
||||
// #include "AsioHacksFwd.h"
|
||||
#include <ace/INET_Addr.h>
|
||||
|
||||
enum RealmFlags
|
||||
{
|
||||
REALM_FLAG_NONE = 0x00,
|
||||
REALM_FLAG_VERSION_MISMATCH = 0x01,
|
||||
REALM_FLAG_OFFLINE = 0x02,
|
||||
REALM_FLAG_SPECIFYBUILD = 0x04,
|
||||
REALM_FLAG_UNK1 = 0x08,
|
||||
REALM_FLAG_UNK2 = 0x10,
|
||||
REALM_FLAG_RECOMMENDED = 0x20,
|
||||
REALM_FLAG_NEW = 0x40,
|
||||
REALM_FLAG_FULL = 0x80
|
||||
};
|
||||
|
||||
struct AC_SHARED_API RealmHandle
|
||||
{
|
||||
RealmHandle() : Realm(0) { }
|
||||
RealmHandle(uint32 index) : Realm(index) { }
|
||||
|
||||
uint32 Realm; // primary key in `realmlist` table
|
||||
|
||||
bool operator<(RealmHandle const& r) const
|
||||
{
|
||||
return Realm < r.Realm;
|
||||
}
|
||||
};
|
||||
|
||||
/// Type of server, this is values from second column of Cfg_Configs.dbc
|
||||
enum RealmType
|
||||
{
|
||||
REALM_TYPE_NORMAL = 0,
|
||||
REALM_TYPE_PVP = 1,
|
||||
REALM_TYPE_NORMAL2 = 4,
|
||||
REALM_TYPE_RP = 6,
|
||||
REALM_TYPE_RPPVP = 8,
|
||||
|
||||
MAX_CLIENT_REALM_TYPE = 14,
|
||||
|
||||
REALM_TYPE_FFA_PVP = 16 // custom, free for all pvp mode like arena PvP in all zones except rest activated places and sanctuaries
|
||||
// replaced by REALM_PVP in realm list
|
||||
};
|
||||
|
||||
// Storage object for a realm
|
||||
struct AC_SHARED_API Realm
|
||||
{
|
||||
RealmHandle Id;
|
||||
uint32 Build;
|
||||
std::unique_ptr<ACE_INET_Addr> ExternalAddress;
|
||||
std::unique_ptr<ACE_INET_Addr> LocalAddress;
|
||||
std::unique_ptr<ACE_INET_Addr> LocalSubnetMask;
|
||||
uint16 Port;
|
||||
std::string Name;
|
||||
uint8 Type;
|
||||
RealmFlags Flags;
|
||||
uint8 Timezone;
|
||||
AccountTypes AllowedSecurityLevel;
|
||||
float PopulationLevel;
|
||||
|
||||
// boost::asio::ip::tcp_endpoint GetAddressForClient(boost::asio::ip::address const& clientAddr) const;
|
||||
};
|
||||
|
||||
#endif // Realm_h__
|
||||
@@ -4,11 +4,14 @@
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "RealmList.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "Log.h"
|
||||
#include "Optional.h"
|
||||
#include "Util.h"
|
||||
|
||||
RealmList::RealmList() : m_NextUpdateTime(time(nullptr)) { }
|
||||
RealmList::RealmList() :
|
||||
_updateInterval(0) { }
|
||||
|
||||
RealmList* RealmList::instance()
|
||||
{
|
||||
@@ -19,81 +22,209 @@ RealmList* RealmList::instance()
|
||||
// Load the realm list from the database
|
||||
void RealmList::Initialize(uint32 updateInterval)
|
||||
{
|
||||
m_UpdateInterval = updateInterval;
|
||||
_updateInterval = updateInterval;
|
||||
|
||||
// Get the content of the realmlist table in the database
|
||||
UpdateRealms(true);
|
||||
}
|
||||
|
||||
void RealmList::UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build)
|
||||
{
|
||||
// Create new if not exist or update existed
|
||||
Realm& realm = m_realms[name];
|
||||
|
||||
realm.m_ID = id;
|
||||
realm.name = name;
|
||||
realm.icon = icon;
|
||||
realm.flag = flag;
|
||||
realm.timezone = timezone;
|
||||
realm.allowedSecurityLevel = allowedSecurityLevel;
|
||||
realm.populationLevel = popu;
|
||||
|
||||
// Append port to IP address.
|
||||
realm.ExternalAddress = address;
|
||||
realm.LocalAddress = localAddr;
|
||||
realm.LocalSubnetMask = localSubmask;
|
||||
realm.gamebuild = build;
|
||||
}
|
||||
|
||||
void RealmList::UpdateIfNeed()
|
||||
{
|
||||
// maybe disabled or updated recently
|
||||
if (!m_UpdateInterval || m_NextUpdateTime > time(nullptr))
|
||||
return;
|
||||
|
||||
m_NextUpdateTime = time(nullptr) + m_UpdateInterval;
|
||||
|
||||
// Clears Realm list
|
||||
m_realms.clear();
|
||||
LoadBuildInfo();
|
||||
|
||||
// Get the content of the realmlist table in the database
|
||||
UpdateRealms();
|
||||
}
|
||||
|
||||
void RealmList::UpdateRealms(bool init)
|
||||
void RealmList::LoadBuildInfo()
|
||||
{
|
||||
LOG_INFO("server", "Updating Realm List...");
|
||||
// 0 1 2 3 4 5 6
|
||||
if (QueryResult result = LoginDatabase.Query("SELECT majorVersion, minorVersion, bugfixVersion, hotfixVersion, build, winChecksumSeed, macChecksumSeed FROM build_info ORDER BY build ASC"))
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
RealmBuildInfo& build = _builds.emplace_back();
|
||||
build.MajorVersion = fields[0].GetUInt32();
|
||||
build.MinorVersion = fields[1].GetUInt32();
|
||||
build.BugfixVersion = fields[2].GetUInt32();
|
||||
std::string hotfixVersion = fields[3].GetString();
|
||||
|
||||
if (hotfixVersion.length() < build.HotfixVersion.size())
|
||||
{
|
||||
std::copy(hotfixVersion.begin(), hotfixVersion.end(), build.HotfixVersion.begin());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::fill(hotfixVersion.begin(), hotfixVersion.end(), '\0');
|
||||
}
|
||||
|
||||
build.Build = fields[4].GetUInt32();
|
||||
std::string windowsHash = fields[5].GetString();
|
||||
|
||||
if (windowsHash.length() == build.WindowsHash.size() * 2)
|
||||
{
|
||||
HexStrToByteArray(windowsHash, build.WindowsHash);
|
||||
}
|
||||
|
||||
std::string macHash = fields[6].GetString();
|
||||
|
||||
if (macHash.length() == build.MacHash.size() * 2)
|
||||
{
|
||||
HexStrToByteArray(macHash, build.MacHash);
|
||||
}
|
||||
} while (result->NextRow());
|
||||
}
|
||||
}
|
||||
|
||||
void RealmList::UpdateRealm(RealmHandle const& id, uint32 build, std::string const& name,
|
||||
ACE_INET_Addr&& address, ACE_INET_Addr&& localAddr, ACE_INET_Addr&& localSubmask,
|
||||
uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population)
|
||||
{
|
||||
// Create new if not exist or update existed
|
||||
Realm& realm = _realms[id];
|
||||
|
||||
realm.Id = id;
|
||||
realm.Build = build;
|
||||
realm.Name = name;
|
||||
realm.Type = icon;
|
||||
realm.Flags = flag;
|
||||
realm.Timezone = timezone;
|
||||
realm.AllowedSecurityLevel = allowedSecurityLevel;
|
||||
realm.PopulationLevel = population;
|
||||
|
||||
if (!realm.ExternalAddress || *realm.ExternalAddress != address)
|
||||
{
|
||||
realm.ExternalAddress = std::make_unique<ACE_INET_Addr>(std::move(address));
|
||||
}
|
||||
|
||||
if (!realm.LocalAddress || *realm.LocalAddress != localAddr)
|
||||
{
|
||||
realm.LocalAddress = std::make_unique<ACE_INET_Addr>(std::move(localAddr));
|
||||
}
|
||||
|
||||
if (!realm.LocalSubnetMask || *realm.LocalSubnetMask != localSubmask)
|
||||
{
|
||||
realm.LocalSubnetMask = std::make_unique<ACE_INET_Addr>(std::move(localSubmask));
|
||||
}
|
||||
|
||||
realm.Port = port;
|
||||
}
|
||||
|
||||
void RealmList::UpdateIfNeed()
|
||||
{
|
||||
// maybe disabled or updated recently
|
||||
if (!_updateInterval || _nextUpdateTime > time(nullptr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_nextUpdateTime = time(nullptr) + _updateInterval;
|
||||
|
||||
// Get the content of the realmlist table in the database
|
||||
UpdateRealms();
|
||||
}
|
||||
|
||||
void RealmList::UpdateRealms()
|
||||
{
|
||||
LOG_DEBUG("server.authserver", "Updating Realm List...");
|
||||
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST);
|
||||
PreparedQueryResult result = LoginDatabase.Query(stmt);
|
||||
|
||||
std::map<RealmHandle, std::string> existingRealms;
|
||||
for (auto const& [handle, realm] : _realms)
|
||||
{
|
||||
existingRealms[handle] = realm.Name;
|
||||
}
|
||||
|
||||
_realms.clear();
|
||||
|
||||
// Circle through results and add them to the realm map
|
||||
if (result)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint32 realmId = fields[0].GetUInt32();
|
||||
std::string name = fields[1].GetString();
|
||||
std::string externalAddress = fields[2].GetString();
|
||||
std::string localAddress = fields[3].GetString();
|
||||
std::string localSubmask = fields[4].GetString();
|
||||
uint16 port = fields[5].GetUInt16();
|
||||
uint8 icon = fields[6].GetUInt8();
|
||||
Field* fields = result->Fetch();
|
||||
uint32 realmId = fields[0].GetUInt32();
|
||||
std::string name = fields[1].GetString();
|
||||
std::string externalAddressString = fields[2].GetString();
|
||||
std::string localAddressString = fields[3].GetString();
|
||||
std::string localSubmaskString = fields[4].GetString();
|
||||
uint16 port = fields[5].GetUInt16();
|
||||
|
||||
Optional<ACE_INET_Addr> externalAddress = ACE_INET_Addr(port, externalAddressString.c_str(), AF_INET);
|
||||
if (!externalAddress)
|
||||
{
|
||||
LOG_ERROR("server.authserver", "Could not resolve address %s for realm \"%s\" id %u", externalAddressString.c_str(), name.c_str(), realmId);
|
||||
continue;
|
||||
}
|
||||
|
||||
Optional<ACE_INET_Addr> localAddress = ACE_INET_Addr(port, localAddressString.c_str(), AF_INET);
|
||||
if (!localAddress)
|
||||
{
|
||||
LOG_ERROR("server.authserver", "Could not resolve localAddress %s for realm \"%s\" id %u", localAddressString.c_str(), name.c_str(), realmId);
|
||||
continue;
|
||||
}
|
||||
|
||||
Optional<ACE_INET_Addr> localSubmask = ACE_INET_Addr(0, localSubmaskString.c_str(), AF_INET);
|
||||
if (!localSubmask)
|
||||
{
|
||||
LOG_ERROR("server.authserver", "Could not resolve localSubnetMask %s for realm \"%s\" id %u", localSubmaskString.c_str(), name.c_str(), realmId);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint8 icon = fields[6].GetUInt8();
|
||||
|
||||
if (icon == REALM_TYPE_FFA_PVP)
|
||||
{
|
||||
icon = REALM_TYPE_PVP;
|
||||
}
|
||||
|
||||
if (icon >= MAX_CLIENT_REALM_TYPE)
|
||||
{
|
||||
icon = REALM_TYPE_NORMAL;
|
||||
}
|
||||
|
||||
RealmFlags flag = RealmFlags(fields[7].GetUInt8());
|
||||
uint8 timezone = fields[8].GetUInt8();
|
||||
uint8 allowedSecurityLevel = fields[9].GetUInt8();
|
||||
float pop = fields[10].GetFloat();
|
||||
uint32 build = fields[11].GetUInt32();
|
||||
|
||||
ACE_INET_Addr externalAddr(port, externalAddress.c_str(), AF_INET);
|
||||
ACE_INET_Addr localAddr(port, localAddress.c_str(), AF_INET);
|
||||
ACE_INET_Addr submask(0, localSubmask.c_str(), AF_INET);
|
||||
RealmHandle id{ realmId };
|
||||
|
||||
UpdateRealm(realmId, name, externalAddr, localAddr, submask, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build);
|
||||
UpdateRealm(id, build, name, std::move(externalAddress.value()), std::move(localAddress.value()), std::move(localSubmask.value()), port, icon, flag,
|
||||
timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop);
|
||||
|
||||
if (init)
|
||||
LOG_INFO("server", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[name].ExternalAddress.get_host_addr(), port);
|
||||
if (!existingRealms.count(id))
|
||||
{
|
||||
LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), externalAddressString.c_str(), port);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("server.authserver", "Updating realm \"%s\" at %s:%u.", name.c_str(), externalAddressString.c_str(), port);
|
||||
}
|
||||
|
||||
existingRealms.erase(id);
|
||||
} while (result->NextRow());
|
||||
}
|
||||
}
|
||||
|
||||
Realm const* RealmList::GetRealm(RealmHandle const& id) const
|
||||
{
|
||||
auto itr = _realms.find(id);
|
||||
if (itr != _realms.end())
|
||||
{
|
||||
return &itr->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RealmBuildInfo const* RealmList::GetBuildInfo(uint32 build) const
|
||||
{
|
||||
for (RealmBuildInfo const& clientBuild : _builds)
|
||||
{
|
||||
if (clientBuild.Build == build)
|
||||
{
|
||||
return &clientBuild;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -7,43 +7,29 @@
|
||||
#ifndef _REALMLIST_H
|
||||
#define _REALMLIST_H
|
||||
|
||||
#include "Common.h"
|
||||
#include <ace/INET_Addr.h>
|
||||
#include "Define.h"
|
||||
#include "Realm.h"
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
|
||||
enum RealmFlags
|
||||
struct RealmBuildInfo
|
||||
{
|
||||
REALM_FLAG_NONE = 0x00,
|
||||
REALM_FLAG_INVALID = 0x01,
|
||||
REALM_FLAG_OFFLINE = 0x02,
|
||||
REALM_FLAG_SPECIFYBUILD = 0x04,
|
||||
REALM_FLAG_UNK1 = 0x08,
|
||||
REALM_FLAG_UNK2 = 0x10,
|
||||
REALM_FLAG_RECOMMENDED = 0x20,
|
||||
REALM_FLAG_NEW = 0x40,
|
||||
REALM_FLAG_FULL = 0x80
|
||||
};
|
||||
|
||||
// Storage object for a realm
|
||||
struct Realm
|
||||
{
|
||||
ACE_INET_Addr ExternalAddress;
|
||||
ACE_INET_Addr LocalAddress;
|
||||
ACE_INET_Addr LocalSubnetMask;
|
||||
std::string name;
|
||||
uint8 icon;
|
||||
RealmFlags flag;
|
||||
uint8 timezone;
|
||||
uint32 m_ID;
|
||||
AccountTypes allowedSecurityLevel;
|
||||
float populationLevel;
|
||||
uint32 gamebuild;
|
||||
uint32 Build;
|
||||
uint32 MajorVersion;
|
||||
uint32 MinorVersion;
|
||||
uint32 BugfixVersion;
|
||||
std::array<char, 4> HotfixVersion;
|
||||
std::array<uint8, 20> WindowsHash;
|
||||
std::array<uint8, 20> MacHash;
|
||||
};
|
||||
|
||||
/// Storage object for the list of realms on the server
|
||||
class RealmList
|
||||
class AC_SHARED_API RealmList
|
||||
{
|
||||
public:
|
||||
typedef std::map<std::string, Realm> RealmMap;
|
||||
typedef std::map<RealmHandle, Realm> RealmMap;
|
||||
|
||||
RealmList();
|
||||
~RealmList() = default;
|
||||
@@ -52,19 +38,23 @@ public:
|
||||
|
||||
void Initialize(uint32 updateInterval);
|
||||
void UpdateIfNeed();
|
||||
void AddRealm(const Realm& NewRealm) { m_realms[NewRealm.name] = NewRealm; }
|
||||
|
||||
[[nodiscard]] RealmMap::const_iterator begin() const { return m_realms.begin(); }
|
||||
[[nodiscard]] RealmMap::const_iterator end() const { return m_realms.end(); }
|
||||
[[nodiscard]] uint32 size() const { return m_realms.size(); }
|
||||
RealmMap const& GetRealms() const { return _realms; }
|
||||
Realm const* GetRealm(RealmHandle const& id) const;
|
||||
|
||||
RealmBuildInfo const* GetBuildInfo(uint32 build) const;
|
||||
|
||||
private:
|
||||
void UpdateRealms(bool init = false);
|
||||
void UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build);
|
||||
void LoadBuildInfo();
|
||||
void UpdateRealms();
|
||||
void UpdateRealm(RealmHandle const& id, uint32 build, std::string const& name,
|
||||
ACE_INET_Addr&& address, ACE_INET_Addr&& localAddr, ACE_INET_Addr&& localSubmask,
|
||||
uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population);
|
||||
|
||||
RealmMap m_realms;
|
||||
uint32 m_UpdateInterval{0};
|
||||
time_t m_NextUpdateTime;
|
||||
std::vector<RealmBuildInfo> _builds;
|
||||
RealmMap _realms;
|
||||
uint32 _updateInterval;
|
||||
time_t _nextUpdateTime;
|
||||
};
|
||||
|
||||
#define sRealmList RealmList::instance()
|
||||
|
||||
@@ -39,8 +39,6 @@ char serviceDescription[] = "AzerothCore World of Warcraft emulator world servic
|
||||
int m_ServiceStatus = -1;
|
||||
#endif
|
||||
|
||||
uint32 realmID; ///< Id of the realm
|
||||
|
||||
/// Print out the usage string for this program on the console.
|
||||
void usage(const char* prog)
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "Master.h"
|
||||
#include "OpenSSLCrypto.h"
|
||||
#include "RARunnable.h"
|
||||
#include "RealmList.h"
|
||||
#include "Realm.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SignalHandler.h"
|
||||
#include "Timer.h"
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "WorldSocket.h"
|
||||
#include "WorldSocketMgr.h"
|
||||
#include "DatabaseLoader.h"
|
||||
#include "Optional.h"
|
||||
#include "SecretMgr.h"
|
||||
#include <ace/Sig_Handler.h>
|
||||
|
||||
@@ -100,6 +101,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
bool LoadRealmInfo();
|
||||
|
||||
Master* Master::instance()
|
||||
{
|
||||
static Master instance;
|
||||
@@ -131,7 +134,9 @@ int Master::Run()
|
||||
return 1;
|
||||
|
||||
// set server offline (not connectable)
|
||||
LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID);
|
||||
LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_VERSION_MISMATCH, realm.Id.Realm);
|
||||
|
||||
LoadRealmInfo();
|
||||
|
||||
// Loading modules configs
|
||||
sConfigMgr->LoadModulesConfigs();
|
||||
@@ -271,7 +276,7 @@ int Master::Run()
|
||||
}
|
||||
|
||||
// set server online (allow connecting now)
|
||||
LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID);
|
||||
LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_VERSION_MISMATCH, realm.Id.Realm);
|
||||
|
||||
LOG_INFO("server", "%s (worldserver-daemon) ready...", GitRevision::GetFullVersion());
|
||||
|
||||
@@ -295,7 +300,7 @@ int Master::Run()
|
||||
}
|
||||
|
||||
// set server offline
|
||||
LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID);
|
||||
LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realm.Id.Realm);
|
||||
|
||||
///- Clean database before leaving
|
||||
ClearOnlineAccounts();
|
||||
@@ -379,16 +384,16 @@ bool Master::_StartDB()
|
||||
return false;
|
||||
|
||||
///- Get the realm Id from the configuration file
|
||||
realmID = sConfigMgr->GetOption<int32>("RealmID", 0);
|
||||
if (!realmID)
|
||||
realm.Id.Realm = sConfigMgr->GetOption<int32>("RealmID", 0);
|
||||
if (!realm.Id.Realm)
|
||||
{
|
||||
LOG_ERROR("server", "Realm ID not defined in configuration file");
|
||||
return false;
|
||||
}
|
||||
else if (realmID > 255)
|
||||
else if (realm.Id.Realm > 255)
|
||||
{
|
||||
/*
|
||||
* Due to the client only being able to read a realmID
|
||||
* Due to the client only being able to read a realm.Id.Realm
|
||||
* with a size of uint8 we can "only" store up to 255 realms
|
||||
* anything further the client will behave anormaly
|
||||
*/
|
||||
@@ -396,7 +401,7 @@ bool Master::_StartDB()
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO("server", "Realm running as realm ID %d", realmID);
|
||||
LOG_INFO("server", "Realm running as realm ID %d", realm.Id.Realm);
|
||||
|
||||
///- Clean the database before starting
|
||||
ClearOnlineAccounts();
|
||||
@@ -424,8 +429,55 @@ void Master::ClearOnlineAccounts()
|
||||
{
|
||||
// Reset online status for all accounts with characters on the current realm
|
||||
// pussywizard: tc query would set online=0 even if logged in on another realm >_>
|
||||
LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online = %u", realmID);
|
||||
LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online = %u", realm.Id.Realm);
|
||||
|
||||
// Reset online status for all characters
|
||||
CharacterDatabase.DirectExecute("UPDATE characters SET online = 0 WHERE online <> 0");
|
||||
}
|
||||
|
||||
bool LoadRealmInfo()
|
||||
{
|
||||
QueryResult result = LoginDatabase.PQuery("SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE id = %u", realm.Id.Realm);
|
||||
if (!result)
|
||||
{
|
||||
LOG_ERROR("server.worldserver", "> Not found realm with ID %u", realm.Id.Realm);
|
||||
return false;
|
||||
}
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
realm.Name = fields[1].GetString();
|
||||
realm.Port = fields[5].GetUInt16();
|
||||
|
||||
Optional<ACE_INET_Addr> externalAddress = ACE_INET_Addr(realm.Port, fields[2].GetCString(), AF_INET);
|
||||
if (!externalAddress)
|
||||
{
|
||||
LOG_ERROR("server.worldserver", "Could not resolve address %s", fields[2].GetString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
Optional<ACE_INET_Addr> localAddress = ACE_INET_Addr(realm.Port, fields[3].GetCString(), AF_INET);
|
||||
if (!localAddress)
|
||||
{
|
||||
LOG_ERROR("server.worldserver", "Could not resolve address %s", fields[3].GetString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
Optional<ACE_INET_Addr> localSubmask = ACE_INET_Addr(0, fields[4].GetCString(), AF_INET);
|
||||
if (!localSubmask)
|
||||
{
|
||||
LOG_ERROR("server.worldserver", "Could not resolve address %s", fields[4].GetString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
realm.ExternalAddress = std::make_unique<ACE_INET_Addr>(*externalAddress);
|
||||
realm.LocalAddress = std::make_unique<ACE_INET_Addr>(*localAddress);
|
||||
realm.LocalSubnetMask = std::make_unique<ACE_INET_Addr>(*localSubmask);
|
||||
|
||||
realm.Type = fields[6].GetUInt8();
|
||||
realm.Flags = RealmFlags(fields[7].GetUInt8());
|
||||
realm.Timezone = fields[8].GetUInt8();
|
||||
realm.AllowedSecurityLevel = AccountTypes(fields[9].GetUInt8());
|
||||
realm.PopulationLevel = fields[10].GetFloat();
|
||||
realm.Build = fields[11].GetUInt32();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
uint32 realmID;
|
||||
void AddScripts() {}
|
||||
bool ArenaSpectator::HandleSpectatorSpectateCommand(ChatHandler* handler, char const* args) { return false; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user