Merge pull request #16696 from TrinityCore/realm6xto335
Core: Backport 6.x realm changes
This commit is contained in:
commit
2e1e608450
23 files changed
+283
-146
No files matched your search
@@ -57,6 +57,7 @@ include_directories(
|
||||
${CMAKE_SOURCE_DIR}/src/server/database
|
||||
${CMAKE_SOURCE_DIR}/src/server/database/Database
|
||||
${CMAKE_SOURCE_DIR}/src/server/database/Logging
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Networking
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Service
|
||||
|
||||
@@ -134,7 +134,7 @@ int main(int argc, char** argv)
|
||||
// Get the list of realms for the server
|
||||
sRealmList->Initialize(*_ioService, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 20));
|
||||
|
||||
if (sRealmList->size() == 0)
|
||||
if (sRealmList->GetRealms().empty())
|
||||
{
|
||||
TC_LOG_ERROR("server.authserver", "No valid realms specified.");
|
||||
StopDB();
|
||||
@@ -194,6 +194,8 @@ int main(int argc, char** argv)
|
||||
|
||||
sAuthSocketMgr.StopNetwork();
|
||||
|
||||
sRealmList->Close();
|
||||
|
||||
// Close the Database Pool and library
|
||||
StopDB();
|
||||
|
||||
|
||||
@@ -16,69 +16,62 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include "Common.h"
|
||||
#include "RealmList.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "RealmList.h"
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
|
||||
namespace boost { namespace asio { namespace ip { class address; } } }
|
||||
|
||||
RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL)), _resolver(nullptr) { }
|
||||
RealmList::RealmList() : _updateInterval(0), _updateTimer(nullptr), _resolver(nullptr) { }
|
||||
RealmList::~RealmList()
|
||||
{
|
||||
delete _resolver;
|
||||
delete _updateTimer;
|
||||
}
|
||||
|
||||
// Load the realm list from the database
|
||||
void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInterval)
|
||||
{
|
||||
_updateInterval = updateInterval;
|
||||
_updateTimer = new boost::asio::deadline_timer(ioService);
|
||||
_resolver = new boost::asio::ip::tcp::resolver(ioService);
|
||||
m_UpdateInterval = updateInterval;
|
||||
|
||||
// Get the content of the realmlist table in the database
|
||||
UpdateRealms(true);
|
||||
UpdateRealms(true, boost::system::error_code());
|
||||
}
|
||||
|
||||
void RealmList::UpdateRealm(uint32 id, const std::string& name, ip::address const& address, ip::address const& localAddr,
|
||||
ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build)
|
||||
void RealmList::Close()
|
||||
{
|
||||
_updateTimer->cancel();
|
||||
}
|
||||
|
||||
void RealmList::UpdateRealm(RealmHandle const& id, uint32 build, const std::string& name, ip::address const& address, ip::address const& localAddr,
|
||||
ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel,
|
||||
float population)
|
||||
{
|
||||
// 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 = population;
|
||||
|
||||
// Append port to IP address.
|
||||
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;
|
||||
realm.ExternalAddress = address;
|
||||
realm.LocalAddress = localAddr;
|
||||
realm.LocalSubnetMask = localSubmask;
|
||||
realm.port = port;
|
||||
realm.gamebuild = build;
|
||||
realm.Port = port;
|
||||
}
|
||||
|
||||
void RealmList::UpdateIfNeed()
|
||||
void RealmList::UpdateRealms(bool init, boost::system::error_code const& error)
|
||||
{
|
||||
// maybe disabled or updated recently
|
||||
if (!m_UpdateInterval || m_NextUpdateTime > time(NULL))
|
||||
if (error)
|
||||
return;
|
||||
|
||||
m_NextUpdateTime = time(NULL) + m_UpdateInterval;
|
||||
|
||||
// Clears Realm list
|
||||
m_realms.clear();
|
||||
|
||||
// Get the content of the realmlist table in the database
|
||||
UpdateRealms();
|
||||
}
|
||||
|
||||
void RealmList::UpdateRealms(bool init)
|
||||
{
|
||||
TC_LOG_INFO("server.authserver", "Updating Realm List...");
|
||||
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST);
|
||||
@@ -130,17 +123,23 @@ void RealmList::UpdateRealms(bool init)
|
||||
|
||||
uint16 port = fields[5].GetUInt16();
|
||||
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();
|
||||
|
||||
UpdateRealm(realmId, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone,
|
||||
(allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build);
|
||||
RealmHandle id{ realmId };
|
||||
|
||||
UpdateRealm(id, build, name, externalAddress, localAddress, localSubmask, port, icon, flag,
|
||||
timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop);
|
||||
|
||||
if (init)
|
||||
TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[name].ExternalAddress.to_string().c_str(), port);
|
||||
TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port);
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
@@ -150,4 +149,19 @@ void RealmList::UpdateRealms(bool init)
|
||||
}
|
||||
while (result->NextRow());
|
||||
}
|
||||
|
||||
if (_updateInterval)
|
||||
{
|
||||
_updateTimer->expires_from_now(boost::posix_time::seconds(_updateInterval));
|
||||
_updateTimer->async_wait(std::bind(&RealmList::UpdateRealms, this, false, std::placeholders::_1));
|
||||
}
|
||||
}
|
||||
|
||||
Realm const* RealmList::GetRealm(RealmHandle const& id) const
|
||||
{
|
||||
auto itr = _realms.find(id);
|
||||
if (itr != _realms.end())
|
||||
return &itr->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -19,48 +19,20 @@
|
||||
#ifndef _REALMLIST_H
|
||||
#define _REALMLIST_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Realm/Realm.h"
|
||||
#include <boost/asio/ip/address.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include "Common.h"
|
||||
#include <boost/asio/deadline_timer.hpp>
|
||||
|
||||
using namespace boost::asio;
|
||||
|
||||
enum RealmFlags
|
||||
{
|
||||
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
|
||||
{
|
||||
ip::address ExternalAddress;
|
||||
ip::address LocalAddress;
|
||||
ip::address LocalSubnetMask;
|
||||
uint16 port;
|
||||
std::string name;
|
||||
uint8 icon;
|
||||
RealmFlags flag;
|
||||
uint8 timezone;
|
||||
uint32 m_ID;
|
||||
AccountTypes allowedSecurityLevel;
|
||||
float populationLevel;
|
||||
uint32 gamebuild;
|
||||
};
|
||||
|
||||
/// Storage object for the list of realms on the server
|
||||
class RealmList
|
||||
{
|
||||
public:
|
||||
typedef std::map<std::string, Realm> RealmMap;
|
||||
typedef std::map<RealmHandle, Realm> RealmMap;
|
||||
|
||||
static RealmList* instance()
|
||||
{
|
||||
@@ -71,25 +43,21 @@ public:
|
||||
~RealmList();
|
||||
|
||||
void Initialize(boost::asio::io_service& ioService, uint32 updateInterval);
|
||||
void Close();
|
||||
|
||||
void UpdateIfNeed();
|
||||
|
||||
void AddRealm(const Realm& NewRealm) { m_realms[NewRealm.name] = NewRealm; }
|
||||
|
||||
RealmMap::const_iterator begin() const { return m_realms.begin(); }
|
||||
RealmMap::const_iterator end() const { return m_realms.end(); }
|
||||
uint32 size() const { return m_realms.size(); }
|
||||
RealmMap const& GetRealms() const { return _realms; }
|
||||
Realm const* GetRealm(RealmHandle const& id) const;
|
||||
|
||||
private:
|
||||
RealmList();
|
||||
|
||||
void UpdateRealms(bool init = false);
|
||||
void UpdateRealm(uint32 id, const std::string& name, ip::address const& address, ip::address const& localAddr,
|
||||
ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build);
|
||||
void UpdateRealms(bool init, boost::system::error_code const& error);
|
||||
void UpdateRealm(RealmHandle const& id, uint32 build, const std::string& name, ip::address const& address, ip::address const& localAddr,
|
||||
ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population);
|
||||
|
||||
RealmMap m_realms;
|
||||
uint32 m_UpdateInterval;
|
||||
time_t m_NextUpdateTime;
|
||||
RealmMap _realms;
|
||||
uint32 _updateInterval;
|
||||
boost::asio::deadline_timer* _updateTimer;
|
||||
boost::asio::ip::tcp::resolver* _resolver;
|
||||
};
|
||||
|
||||
|
||||
@@ -844,7 +844,7 @@ tcp::endpoint const GetAddressForClient(Realm const& realm, ip::address const& c
|
||||
realmIp = realm.ExternalAddress;
|
||||
}
|
||||
|
||||
tcp::endpoint endpoint(realmIp, realm.port);
|
||||
tcp::endpoint endpoint(realmIp, realm.Port);
|
||||
|
||||
// Return external IP
|
||||
return endpoint;
|
||||
@@ -880,22 +880,19 @@ void AuthSession::RealmListCallback(PreparedQueryResult result)
|
||||
} while (result->NextRow());
|
||||
}
|
||||
|
||||
// Update realm list if need
|
||||
sRealmList->UpdateIfNeed();
|
||||
|
||||
// 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 (RealmList::RealmMap::value_type const& i : sRealmList->GetRealms())
|
||||
{
|
||||
const Realm &realm = i->second;
|
||||
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 = AuthHelper::GetBuildInfo(realm.Build);
|
||||
if (!okBuild)
|
||||
{
|
||||
if (!buildInfo)
|
||||
@@ -907,7 +904,7 @@ void AuthSession::RealmListCallback(PreparedQueryResult result)
|
||||
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;
|
||||
@@ -915,19 +912,19 @@ void AuthSession::RealmListCallback(PreparedQueryResult result)
|
||||
name = ss.str();
|
||||
}
|
||||
|
||||
uint8 lock = (realm.allowedSecurityLevel > _accountInfo.SecurityLevel) ? 1 : 0;
|
||||
uint8 lock = (realm.AllowedSecurityLevel > _accountInfo.SecurityLevel) ? 1 : 0;
|
||||
|
||||
pkt << uint8(realm.icon); // realm type
|
||||
pkt << uint8(realm.Type); // realm type
|
||||
if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients
|
||||
pkt << uint8(lock); // if 1, then realm locked
|
||||
pkt << uint8(flag); // RealmFlags
|
||||
pkt << name;
|
||||
pkt << boost::lexical_cast<std::string>(GetAddressForClient(realm, GetRemoteIpAddress()));
|
||||
pkt << float(realm.populationLevel);
|
||||
pkt << uint8(characterCounts[realm.m_ID]);
|
||||
pkt << uint8(realm.timezone); // realm category
|
||||
pkt << float(realm.PopulationLevel);
|
||||
pkt << uint8(characterCounts[realm.Id.Realm]);
|
||||
pkt << uint8(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
|
||||
|
||||
|
||||
@@ -462,7 +462,7 @@ void AccountMgr::LoadRBAC()
|
||||
while (result->NextRow());
|
||||
|
||||
TC_LOG_DEBUG("rbac", "AccountMgr::LoadRBAC: Loading default permissions");
|
||||
result = LoginDatabase.PQuery("SELECT secId, permissionId FROM rbac_default_permissions WHERE (realmId = %u OR realmId = -1) ORDER BY secId ASC", realmID);
|
||||
result = LoginDatabase.PQuery("SELECT secId, permissionId FROM rbac_default_permissions WHERE (realmId = %u OR realmId = -1) ORDER BY secId ASC", realm.Id.Realm);
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_INFO("server.loading", ">> Loaded 0 default permission definitions. DB table `rbac_default_permissions` is empty.");
|
||||
|
||||
@@ -130,7 +130,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction&
|
||||
else
|
||||
{
|
||||
bidderAccId = sObjectMgr->GetPlayerAccountIdByGUID(bidderGuid);
|
||||
logGmTrade = AccountMgr::HasPermission(bidderAccId, rbac::RBAC_PERM_LOG_GM_TRADE, realmID);
|
||||
logGmTrade = AccountMgr::HasPermission(bidderAccId, rbac::RBAC_PERM_LOG_GM_TRADE, realm.Id.Realm);
|
||||
|
||||
if (logGmTrade && !sObjectMgr->GetPlayerNameByGUID(bidderGuid, bidderName))
|
||||
bidderName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN);
|
||||
|
||||
@@ -196,6 +196,7 @@ include_directories(
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Networking
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Realm
|
||||
${MYSQL_INCLUDE_DIR}
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
${VALGRIND_INCLUDE_DIR}
|
||||
|
||||
@@ -108,7 +108,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 == NULL && target_account == 0)
|
||||
|
||||
|
||||
@@ -627,13 +627,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);
|
||||
|
||||
@@ -569,7 +569,7 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std
|
||||
team = Player::TeamForRace(fields[1].GetUInt8());
|
||||
friendAccountId = fields[2].GetUInt32();
|
||||
|
||||
if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID)))
|
||||
if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realm.Id.Realm)))
|
||||
{
|
||||
if (friendGuid)
|
||||
{
|
||||
|
||||
@@ -1220,7 +1220,7 @@ void WorldSession::LoadPermissions()
|
||||
uint32 id = GetAccountId();
|
||||
uint8 secLevel = GetSecurity();
|
||||
|
||||
_RBACData = new rbac::RBACData(id, _accountName, realmID, secLevel);
|
||||
_RBACData = new rbac::RBACData(id, _accountName, realm.Id.Realm, secLevel);
|
||||
_RBACData->LoadFromDB();
|
||||
}
|
||||
|
||||
@@ -1230,9 +1230,9 @@ PreparedQueryResultFuture WorldSession::LoadPermissionsAsync()
|
||||
uint8 secLevel = GetSecurity();
|
||||
|
||||
TC_LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: %u, Name: %s, realmId: %d, secLevel: %u]",
|
||||
id, _accountName.c_str(), realmID, secLevel);
|
||||
id, _accountName.c_str(), realm.Id.Realm, secLevel);
|
||||
|
||||
_RBACData = new rbac::RBACData(id, _accountName, realmID, secLevel);
|
||||
_RBACData = new rbac::RBACData(id, _accountName, realm.Id.Realm, secLevel);
|
||||
return _RBACData->LoadFromDBAsync();
|
||||
}
|
||||
|
||||
@@ -1310,7 +1310,7 @@ bool WorldSession::HasPermission(uint32 permission)
|
||||
|
||||
bool hasPermission = _RBACData->HasPermission(permission);
|
||||
TC_LOG_DEBUG("rbac", "WorldSession::HasPermission [AccountId: %u, Name: %s, realmId: %d]",
|
||||
_RBACData->GetId(), _RBACData->GetName().c_str(), realmID);
|
||||
_RBACData->GetId(), _RBACData->GetName().c_str(), realm.Id.Realm);
|
||||
|
||||
return hasPermission;
|
||||
}
|
||||
@@ -1318,7 +1318,7 @@ bool WorldSession::HasPermission(uint32 permission)
|
||||
void WorldSession::InvalidateRBACData()
|
||||
{
|
||||
TC_LOG_DEBUG("rbac", "WorldSession::Invalidaterbac::RBACData [AccountId: %u, Name: %s, realmId: %d]",
|
||||
_RBACData->GetId(), _RBACData->GetName().c_str(), realmID);
|
||||
_RBACData->GetId(), _RBACData->GetName().c_str(), realm.Id.Realm);
|
||||
delete _RBACData;
|
||||
_RBACData = NULL;
|
||||
}
|
||||
|
||||
@@ -414,7 +414,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
|
||||
|
||||
// Get the account information from the auth database
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME);
|
||||
stmt->setInt32(0, int32(realmID));
|
||||
stmt->setInt32(0, int32(realm.Id.Realm));
|
||||
stmt->setString(1, authSession->Account);
|
||||
|
||||
_queryCallback = std::bind(&WorldSocket::HandleAuthSessionCallback, this, authSession, std::placeholders::_1);
|
||||
@@ -457,7 +457,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<AuthSession> authSes
|
||||
return;
|
||||
}
|
||||
|
||||
if (authSession->RealmID != realmID)
|
||||
if (authSession->RealmID != realm.Id.Realm)
|
||||
{
|
||||
SendAuthResponseError(REALM_LIST_REALM_NOT_FOUND);
|
||||
TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (bad realm).");
|
||||
|
||||
@@ -1369,7 +1369,7 @@ void World::SetInitialWorldSettings()
|
||||
uint32 server_type = IsFFAPvPRealm() ? uint32(REALM_TYPE_PVP) : getIntConfig(CONFIG_GAME_TYPE);
|
||||
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
|
||||
|
||||
///- Load the DBC files
|
||||
TC_LOG_INFO("server.loading", "Initialize data stores...");
|
||||
@@ -1790,7 +1790,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);
|
||||
@@ -2103,7 +2103,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);
|
||||
@@ -2826,13 +2826,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);
|
||||
LoginDatabase.Execute(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);
|
||||
LoginDatabase.Execute(stmt);
|
||||
}
|
||||
}
|
||||
@@ -2960,7 +2960,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)
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "SharedDefines.h"
|
||||
#include "QueryResult.h"
|
||||
#include "Callback.h"
|
||||
#include "Realm/Realm.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
@@ -446,18 +447,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
|
||||
@@ -882,7 +871,7 @@ class World
|
||||
std::deque<std::future<PreparedQueryResult>> m_realmCharCallbacks;
|
||||
};
|
||||
|
||||
extern uint32 realmID;
|
||||
extern Realm realm;
|
||||
|
||||
#define sWorld World::instance()
|
||||
#endif
|
||||
|
||||
@@ -164,7 +164,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)
|
||||
|
||||
@@ -1588,7 +1588,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 result = LoginDatabase.Query(stmt);
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ public:
|
||||
|
||||
if (!rdata)
|
||||
{
|
||||
data->rbac = new rbac::RBACData(accountId, accountName, realmID, AccountMgr::GetSecurity(accountId, realmID));
|
||||
data->rbac = new rbac::RBACData(accountId, accountName, realm.Id.Realm, AccountMgr::GetSecurity(accountId, realm.Id.Realm));
|
||||
data->rbac->LoadFromDB();
|
||||
data->needDelete = true;
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
ObjectGuid targetGuid = sObjectMgr->GetPlayerGUIDByName(target);
|
||||
uint32 accountId = sObjectMgr->GetPlayerAccountIdByGUID(targetGuid);
|
||||
// Target must exist and have administrative rights
|
||||
if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realmID))
|
||||
if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realm.Id.Realm))
|
||||
{
|
||||
handler->SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A);
|
||||
return true;
|
||||
@@ -119,7 +119,7 @@ public:
|
||||
|
||||
// Assign ticket
|
||||
SQLTransaction trans = SQLTransaction(NULL);
|
||||
ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(AccountMgr::GetSecurity(accountId, realmID)));
|
||||
ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(AccountMgr::GetSecurity(accountId, realm.Id.Realm)));
|
||||
ticket->SaveToDB(trans);
|
||||
sTicketMgr->UpdateLastChange();
|
||||
|
||||
@@ -387,7 +387,7 @@ public:
|
||||
{
|
||||
ObjectGuid guid = ticket->GetAssignedToGUID();
|
||||
uint32 accountId = sObjectMgr->GetPlayerAccountIdByGUID(guid);
|
||||
security = AccountMgr::GetSecurity(accountId, realmID);
|
||||
security = AccountMgr::GetSecurity(accountId, realm.Id.Realm);
|
||||
}
|
||||
|
||||
// Check security
|
||||
|
||||
@@ -16,6 +16,7 @@ file(GLOB_RECURSE sources_DataStores DataStores/*.cpp DataStores/*.h)
|
||||
file(GLOB_RECURSE sources_Dynamic Dynamic/*.cpp Dynamic/*.h)
|
||||
file(GLOB_RECURSE sources_Networking Networking/*.cpp Networking/*.h)
|
||||
file(GLOB_RECURSE sources_Packets Packets/*.cpp Packets/*.h)
|
||||
file(GLOB_RECURSE sources_Realm Realm/*.cpp Realm/*.h)
|
||||
if( WIN32 )
|
||||
file(GLOB_RECURSE sources_Service Service/*.cpp Service/*.h)
|
||||
endif( WIN32 )
|
||||
@@ -36,6 +37,7 @@ set(shared_STAT_SRCS
|
||||
${sources_Dynamic}
|
||||
${sources_Networking}
|
||||
${sources_Packets}
|
||||
${sources_Realm}
|
||||
${sources_Utilities}
|
||||
${sources_Service}
|
||||
${sources_localdir}
|
||||
@@ -44,6 +46,7 @@ set(shared_STAT_SRCS
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Dynamic
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Networking
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Realm
|
||||
${CMAKE_SOURCE_DIR}/dep/cppformat
|
||||
${CMAKE_SOURCE_DIR}/src/common/
|
||||
${CMAKE_SOURCE_DIR}/src/common/Debugging
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Realm.h"
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef Realm_h__
|
||||
#define Realm_h__
|
||||
|
||||
#include "Common.h"
|
||||
#include <boost/asio/ip/address.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
|
||||
using namespace boost::asio;
|
||||
|
||||
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 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 Realm
|
||||
{
|
||||
RealmHandle Id;
|
||||
uint32 Build;
|
||||
ip::address ExternalAddress;
|
||||
ip::address LocalAddress;
|
||||
ip::address LocalSubnetMask;
|
||||
uint16 Port;
|
||||
std::string Name;
|
||||
uint8 Type; // icon
|
||||
RealmFlags Flags;
|
||||
uint8 Timezone;
|
||||
AccountTypes AllowedSecurityLevel;
|
||||
float PopulationLevel;
|
||||
};
|
||||
|
||||
#endif // Realm_h__
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "OpenSSLCrypto.h"
|
||||
#include "ProcessPriority.h"
|
||||
#include "BigNumber.h"
|
||||
#include "RealmList.h"
|
||||
#include "World.h"
|
||||
#include "MapManager.h"
|
||||
#include "InstanceSaveMgr.h"
|
||||
@@ -47,6 +46,7 @@
|
||||
#include "GitRevision.h"
|
||||
#include "WorldSocket.h"
|
||||
#include "WorldSocketMgr.h"
|
||||
#include "Realm/Realm.h"
|
||||
#include "DatabaseLoader.h"
|
||||
#include "AppenderDB.h"
|
||||
|
||||
@@ -81,7 +81,7 @@ uint32 _maxCoreStuckTimeInMs(0);
|
||||
WorldDatabaseWorkerPool WorldDatabase; ///< Accessor to the world database
|
||||
CharacterDatabaseWorkerPool CharacterDatabase; ///< Accessor to the character database
|
||||
LoginDatabaseWorkerPool LoginDatabase; ///< Accessor to the realm/login database
|
||||
uint32 realmID; ///< Id of the realm
|
||||
Realm realm;
|
||||
|
||||
void SignalHandler(const boost::system::error_code& error, int signalNumber);
|
||||
void FreezeDetectorHandler(const boost::system::error_code& error);
|
||||
@@ -92,6 +92,7 @@ void WorldUpdateLoop();
|
||||
void ClearOnlineAccounts();
|
||||
void ShutdownCLIThread(std::thread* cliThread);
|
||||
void ShutdownThreadPool(std::vector<std::thread>& threadPool);
|
||||
bool LoadRealmInfo();
|
||||
variables_map GetConsoleArguments(int argc, char** argv, std::string& cfg_file, std::string& cfg_service);
|
||||
|
||||
/// Launch the Trinity server
|
||||
@@ -188,7 +189,9 @@ extern int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
// 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 WHERE id = '%d'", REALM_FLAG_OFFLINE, realm.Id.Realm);
|
||||
|
||||
LoadRealmInfo();
|
||||
|
||||
// Initialize the World
|
||||
sWorld->SetInitialWorldSettings();
|
||||
@@ -223,7 +226,9 @@ extern int main(int argc, char** argv)
|
||||
sWorldSocketMgr.StartNetwork(_ioService, worldListener, worldPort);
|
||||
|
||||
// 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_OFFLINE, realm.Id.Realm);
|
||||
realm.PopulationLevel = 0.0f;
|
||||
realm.Flags = RealmFlags(realm.Flags & ~uint32(REALM_FLAG_OFFLINE));
|
||||
|
||||
// Start the freeze check callback cycle in 5 seconds (cycle itself is 1 sec)
|
||||
if (int coreStuckTime = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0))
|
||||
@@ -259,7 +264,7 @@ extern int main(int argc, char** argv)
|
||||
sScriptMgr->Unload();
|
||||
|
||||
// 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 up threads if any
|
||||
if (soapThread != nullptr)
|
||||
@@ -441,6 +446,59 @@ AsyncAcceptor* StartRaSocketAcceptor(boost::asio::io_service& ioService)
|
||||
return acceptor;
|
||||
}
|
||||
|
||||
bool LoadRealmInfo()
|
||||
{
|
||||
boost::asio::ip::tcp::resolver resolver(_ioService);
|
||||
boost::asio::ip::tcp::resolver::iterator end;
|
||||
|
||||
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)
|
||||
return false;
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
realm.Name = fields[1].GetString();
|
||||
boost::asio::ip::tcp::resolver::query externalAddressQuery(ip::tcp::v4(), fields[2].GetString(), "");
|
||||
|
||||
boost::system::error_code ec;
|
||||
boost::asio::ip::tcp::resolver::iterator endPoint = resolver.resolve(externalAddressQuery, ec);
|
||||
if (endPoint == end || ec)
|
||||
{
|
||||
TC_LOG_ERROR("server.worldserver", "Could not resolve address %s", fields[2].GetString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
realm.ExternalAddress = (*endPoint).endpoint().address();
|
||||
|
||||
boost::asio::ip::tcp::resolver::query localAddressQuery(ip::tcp::v4(), fields[3].GetString(), "");
|
||||
endPoint = resolver.resolve(localAddressQuery, ec);
|
||||
if (endPoint == end || ec)
|
||||
{
|
||||
TC_LOG_ERROR("server.worldserver", "Could not resolve address %s", fields[3].GetString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
realm.LocalAddress = (*endPoint).endpoint().address();
|
||||
|
||||
boost::asio::ip::tcp::resolver::query localSubmaskQuery(ip::tcp::v4(), fields[4].GetString(), "");
|
||||
endPoint = resolver.resolve(localSubmaskQuery, ec);
|
||||
if (endPoint == end || ec)
|
||||
{
|
||||
TC_LOG_ERROR("server.worldserver", "Could not resolve address %s", fields[4].GetString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
realm.LocalSubnetMask = (*endPoint).endpoint().address();
|
||||
|
||||
realm.Port = fields[5].GetUInt16();
|
||||
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;
|
||||
}
|
||||
|
||||
/// Initialize connection to the databases
|
||||
bool StartDB()
|
||||
{
|
||||
@@ -457,13 +515,14 @@ bool StartDB()
|
||||
return false;
|
||||
|
||||
///- Get the realm Id from the configuration file
|
||||
realmID = sConfigMgr->GetIntDefault("RealmID", 0);
|
||||
if (!realmID)
|
||||
realm.Id.Realm = sConfigMgr->GetIntDefault("RealmID", 0);
|
||||
if (!realm.Id.Realm)
|
||||
{
|
||||
TC_LOG_ERROR("server.worldserver", "Realm ID not defined in configuration file");
|
||||
return false;
|
||||
}
|
||||
TC_LOG_INFO("server.worldserver", "Realm running as realm ID %d", realmID);
|
||||
|
||||
TC_LOG_INFO("server.worldserver", "Realm running as realm ID %d", realm.Id.Realm);
|
||||
|
||||
///- Clean the database before starting
|
||||
ClearOnlineAccounts();
|
||||
@@ -490,7 +549,7 @@ void StopDB()
|
||||
void ClearOnlineAccounts()
|
||||
{
|
||||
// Reset online status for all accounts with characters on the current realm
|
||||
LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = %d)", realmID);
|
||||
LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = %d)", realm.Id.Realm);
|
||||
|
||||
// Reset online status for all characters
|
||||
CharacterDatabase.DirectExecute("UPDATE characters SET online = 0 WHERE online <> 0");
|
||||
|
||||
Reference in new issue
Block a user