mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-24 19:06:49 +01:00
Merge remote-tracking branch 'tc/3.3.5' into 4.3.4
Note: additional hand-picked ports from 6.x to fix build Conflicts: sql/updates/world/2016_02_22_00_world.sql sql/updates/world/2016_02_22_01_world.sql sql/updates/world/2016_02_22_02_world.sql sql/updates/world/2016_03_07_00_world.sql src/server/authserver/Realms/RealmList.cpp src/server/authserver/Realms/RealmList.h src/server/authserver/Server/AuthSession.cpp src/server/game/Accounts/AccountMgr.cpp src/server/game/AuctionHouse/AuctionHouseMgr.cpp src/server/game/Chat/Chat.cpp src/server/game/Conditions/ConditionMgr.cpp src/server/game/Conditions/ConditionMgr.h src/server/game/Entities/Player/Player.cpp src/server/game/Handlers/CharacterHandler.cpp src/server/game/Handlers/MiscHandler.cpp src/server/game/Scripting/ScriptLoader.cpp src/server/game/Scripting/ScriptLoader.h src/server/game/Server/WorldSession.cpp src/server/game/Server/WorldSocket.cpp src/server/game/World/World.cpp src/server/game/World/World.h src/server/scripts/CMakeLists.txt src/server/scripts/Commands/cs_gm.cpp src/server/scripts/Commands/cs_misc.cpp src/server/scripts/Commands/cs_rbac.cpp src/server/scripts/Commands/cs_ticket.cpp src/server/scripts/Commands/cs_wp.cpp src/server/scripts/EasternKingdoms/CMakeLists.txt src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp src/server/scripts/Kalimdor/CMakeLists.txt src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp src/server/scripts/Kalimdor/zone_orgrimmar.cpp src/server/scripts/OutdoorPvP/CMakeLists.txt src/server/scripts/Spells/spell_dk.cpp src/server/scripts/Spells/spell_hunter.cpp src/server/shared/CMakeLists.txt src/server/worldserver/CMakeLists.txt src/server/worldserver/Main.cpp src/tools/mmaps_generator/CMakeLists.txt
This commit is contained in:
@@ -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
|
||||
@@ -79,10 +80,10 @@ if( NOT WIN32 )
|
||||
endif()
|
||||
|
||||
target_link_libraries(authserver
|
||||
common
|
||||
shared
|
||||
format
|
||||
database
|
||||
common
|
||||
format
|
||||
${MYSQL_LIBRARY}
|
||||
${OPENSSL_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
|
||||
@@ -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,104 +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 "Util.h"
|
||||
#include "RealmList.h"
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
|
||||
ip::tcp::endpoint Realm::GetAddressForClient(ip::address const& clientAddr) const
|
||||
{
|
||||
ip::address realmIp;
|
||||
|
||||
// Attempt to send best address for client
|
||||
if (clientAddr.is_loopback())
|
||||
{
|
||||
// Try guessing if realm is also connected locally
|
||||
if (LocalAddress.is_loopback() || ExternalAddress.is_loopback())
|
||||
realmIp = clientAddr;
|
||||
else
|
||||
{
|
||||
// Assume that user connecting from the machine that authserver is located on
|
||||
// has all realms available in his local network
|
||||
realmIp = LocalAddress;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (clientAddr.is_v4() &&
|
||||
(clientAddr.to_v4().to_ulong() & LocalSubnetMask.to_v4().to_ulong()) ==
|
||||
(LocalAddress.to_v4().to_ulong() & LocalSubnetMask.to_v4().to_ulong()))
|
||||
{
|
||||
realmIp = LocalAddress;
|
||||
}
|
||||
else
|
||||
realmIp = ExternalAddress;
|
||||
}
|
||||
|
||||
ip::tcp::endpoint endpoint(realmIp, port);
|
||||
|
||||
// Return external IP
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL)), _resolver(nullptr)
|
||||
{
|
||||
}
|
||||
namespace boost { namespace asio { namespace ip { class address; } } }
|
||||
|
||||
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(Battlenet::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;
|
||||
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);
|
||||
@@ -165,17 +123,25 @@ 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();
|
||||
uint8 region = fields[12].GetUInt8();
|
||||
uint8 battlegroup = fields[13].GetUInt8();
|
||||
|
||||
UpdateRealm(realmId, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone,
|
||||
(allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build);
|
||||
Battlenet::RealmHandle id{ region, battlegroup, 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)
|
||||
{
|
||||
@@ -185,4 +151,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(Battlenet::RealmHandle const& id) const
|
||||
{
|
||||
auto itr = _realms.find(id);
|
||||
if (itr != _realms.end())
|
||||
return &itr->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -19,50 +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;
|
||||
|
||||
ip::tcp::endpoint GetAddressForClient(ip::address const& clientAddr) const;
|
||||
};
|
||||
|
||||
/// Storage object for the list of realms on the server
|
||||
class RealmList
|
||||
{
|
||||
public:
|
||||
typedef std::map<std::string, Realm> RealmMap;
|
||||
typedef std::map<Battlenet::RealmHandle, Realm> RealmMap;
|
||||
|
||||
static RealmList* instance()
|
||||
{
|
||||
@@ -73,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(Battlenet::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(Battlenet::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;
|
||||
};
|
||||
|
||||
|
||||
@@ -571,6 +571,8 @@ bool AuthSession::HandleLogonProof()
|
||||
TC_LOG_DEBUG("server.authserver", "'%s:%d' User '%s' successfully authenticated", GetRemoteIpAddress().to_string().c_str(), 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->setString(0, K.AsHexStr());
|
||||
stmt->setString(1, GetRemoteIpAddress().to_string().c_str());
|
||||
@@ -842,22 +844,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)
|
||||
@@ -869,7 +868,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;
|
||||
@@ -877,19 +876,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>(realm.GetAddressForClient(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
|
||||
|
||||
@@ -953,6 +952,7 @@ void AuthSession::SetVSFields(const std::string& rI)
|
||||
x.SetBinary(sha.GetDigest(), sha.GetLength());
|
||||
v = g.ModExp(x, N);
|
||||
|
||||
// No SQL injection (username escaped)
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_VS);
|
||||
stmt->setString(0, v.AsHexStr());
|
||||
stmt->setString(1, s.AsHexStr());
|
||||
|
||||
@@ -137,6 +137,26 @@ WrongPass.Logging = 0
|
||||
|
||||
BanExpiryCheckInterval = 60
|
||||
|
||||
#
|
||||
# SourceDirectory
|
||||
# Description: The path to your TrinityCore source directory.
|
||||
# If the path is left empty, the built-in CMAKE_SOURCE_DIR is used.
|
||||
# Example: "../TrinityCore"
|
||||
# Default: ""
|
||||
|
||||
SourceDirectory = ""
|
||||
|
||||
#
|
||||
# MySQLExecutable
|
||||
# Description: The path to your mysql cli binary.
|
||||
# If the path is left empty, built-in path from cmake is used.
|
||||
# Example: "C:/Program Files/MySQL/MySQL Server 5.6/bin/mysql.exe"
|
||||
# "mysql.exe"
|
||||
# "/usr/bin/mysql"
|
||||
# Default: ""
|
||||
|
||||
MySQLExecutable = ""
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
@@ -180,26 +200,6 @@ LoginDatabase.WorkerThreads = 1
|
||||
|
||||
Updates.EnableDatabases = 0
|
||||
|
||||
#
|
||||
# Updates.SourcePath
|
||||
# Description: The path to your TrinityCore source directory.
|
||||
# If the path is left empty, built-in CMAKE_SOURCE_DIR is used.
|
||||
# Example: "../TrinityCore"
|
||||
# Default: ""
|
||||
|
||||
Updates.SourcePath = ""
|
||||
|
||||
#
|
||||
# Updates.MySqlCLIPath
|
||||
# Description: The path to your mysql cli binary.
|
||||
# If the path is left empty, built-in path from cmake is used.
|
||||
# Example: "C:/Program Files/MySQL/MySQL Server 5.6/bin/mysql.exe"
|
||||
# "mysql.exe"
|
||||
# "/usr/bin/mysql"
|
||||
# Default: ""
|
||||
|
||||
Updates.MySqlCLIPath = ""
|
||||
|
||||
#
|
||||
# Updates.AutoSetup
|
||||
# Description: Auto populate empty databases.
|
||||
|
||||
Reference in New Issue
Block a user