Big update.

This commit is contained in:
UltraNix
2022-03-12 22:28:00 +01:00
parent 6006eeeb01
commit 12d41d1314
2064 changed files with 427245 additions and 268481 deletions

View File

@@ -46,13 +46,13 @@ char* DBCDatabaseLoader::Load(uint32& records, char**& indexTable)
// Check if sql index pos is valid
if (int32(result->GetFieldCount() - 1) < _sqlIndexPos)
{
ASSERT(false, "Invalid index pos for dbc: '%s'", _sqlTableName);
ASSERT(false, "Invalid index pos for dbc: '{}'", _sqlTableName);
return nullptr;
}
// Resize index table
// database query *MUST* contain ORDER BY `index_field` DESC clause
uint32 indexTableSize = std::max(records, (*result)[_sqlIndexPos].GetUInt32() + 1);
uint32 indexTableSize = std::max(records, (*result)[_sqlIndexPos].Get<uint32>() + 1);
if (indexTableSize > records)
{
char** tmpIdxTable = new char* [indexTableSize];
@@ -70,7 +70,7 @@ char* DBCDatabaseLoader::Load(uint32& records, char**& indexTable)
do
{
Field* fields = result->Fetch();
uint32 indexValue = fields[_sqlIndexPos].GetUInt32();
uint32 indexValue = fields[_sqlIndexPos].Get<uint32>();
char* dataValue = indexTable[indexValue];
// If exist in DBC file override from DB
@@ -86,34 +86,34 @@ char* DBCDatabaseLoader::Load(uint32& records, char**& indexTable)
switch (*dbcFormat)
{
case FT_FLOAT:
*reinterpret_cast<float*>(&dataValue[dataOffset]) = fields[sqlColumnNumber].GetFloat();
*reinterpret_cast<float*>(&dataValue[dataOffset]) = fields[sqlColumnNumber].Get<float>();
dataOffset += sizeof(float);
break;
case FT_IND:
case FT_INT:
*reinterpret_cast<uint32*>(&dataValue[dataOffset]) = fields[sqlColumnNumber].GetUInt32();
*reinterpret_cast<uint32*>(&dataValue[dataOffset]) = fields[sqlColumnNumber].Get<uint32>();
dataOffset += sizeof(uint32);
break;
case FT_BYTE:
*reinterpret_cast<uint8*>(&dataValue[dataOffset]) = fields[sqlColumnNumber].GetUInt8();
*reinterpret_cast<uint8*>(&dataValue[dataOffset]) = fields[sqlColumnNumber].Get<uint8>();
dataOffset += sizeof(uint8);
break;
case FT_STRING:
*reinterpret_cast<char**>(&dataValue[dataOffset]) = CloneStringToPool(fields[sqlColumnNumber].GetString());
*reinterpret_cast<char**>(&dataValue[dataOffset]) = CloneStringToPool(fields[sqlColumnNumber].Get<std::string>());
dataOffset += sizeof(char*);
break;
case FT_SORT:
case FT_NA:
break;
default:
ASSERT(false, "Unsupported data type '%c' in table '%s'", *dbcFormat, _sqlTableName);
ASSERT(false, "Unsupported data type '%c' in table '{}'", *dbcFormat, _sqlTableName);
return nullptr;
}
++sqlColumnNumber;
}
ASSERT(sqlColumnNumber == result->GetFieldCount(), "SQL format string does not match database for table: '%s'", _sqlTableName);
ASSERT(sqlColumnNumber == result->GetFieldCount(), "SQL format string does not match database for table: '{}'", _sqlTableName);
ASSERT(dataOffset == _recordSize);
} while (result->NextRow());

View File

@@ -18,6 +18,23 @@
#ifndef DBCENUMS_H
#define DBCENUMS_H
#pragma pack(push, 1)
struct DBCPosition2D
{
float X;
float Y;
};
struct DBCPosition3D
{
float X;
float Y;
float Z;
};
#pragma pack(pop)
// Client expected level limitation, like as used in DBC item max levels for "until max player level"
// use as default max player level, must be fit max level for used client
// also see MAX_LEVEL and STRONG_MAX_LEVEL define
@@ -31,7 +48,7 @@
// also see MAX_LEVEL and GT_MAX_LEVEL define
#define STRONG_MAX_LEVEL 255
enum BattlegroundBracketId : uint8 // bracketId for level ranges
enum BattlegroundBracketId // bracketId for level ranges
{
BG_BRACKET_ID_FIRST = 0,
BG_BRACKET_ID_LAST = 15

View File

@@ -21,124 +21,9 @@
#include "Common.h"
#include "DBCStorageIterator.h"
#include "Errors.h"
#include <G3D/AABox.h>
#include <G3D/Vector3.h>
#include <cstring>
#include <vector>
// Structures for M4 file. Source: https://wowdev.wiki
template<typename T>
struct M2SplineKey
{
T p0;
T p1;
T p2;
};
struct M2Header
{
char Magic[4]; // "MD20"
uint32 Version; // The version of the format.
uint32 lName; // Length of the model's name including the trailing \0
uint32 ofsName; // Offset to the name, it seems like models can get reloaded by this name.should be unique, i guess.
uint32 GlobalModelFlags; // 0x0001: tilt x, 0x0002: tilt y, 0x0008: add 2 fields in header, 0x0020: load .phys data (MoP+), 0x0080: has _lod .skin files (MoP?+), 0x0100: is camera related.
uint32 nGlobalSequences;
uint32 ofsGlobalSequences; // A list of timestamps.
uint32 nAnimations;
uint32 ofsAnimations; // Information about the animations in the model.
uint32 nAnimationLookup;
uint32 ofsAnimationLookup; // Mapping of global IDs to the entries in the Animation sequences block.
uint32 nBones; // MAX_BONES = 0x100
uint32 ofsBones; // Information about the bones in this model.
uint32 nKeyBoneLookup;
uint32 ofsKeyBoneLookup; // Lookup table for key skeletal bones.
uint32 nVertices;
uint32 ofsVertices; // Vertices of the model.
uint32 nViews; // Views (LOD) are now in .skins.
uint32 nSubmeshAnimations;
uint32 ofsSubmeshAnimations; // Submesh color and alpha animations definitions.
uint32 nTextures;
uint32 ofsTextures; // Textures of this model.
uint32 nTransparency;
uint32 ofsTransparency; // Transparency of textures.
uint32 nUVAnimation;
uint32 ofsUVAnimation;
uint32 nTexReplace;
uint32 ofsTexReplace; // Replaceable Textures.
uint32 nRenderFlags;
uint32 ofsRenderFlags; // Blending modes / render flags.
uint32 nBoneLookupTable;
uint32 ofsBoneLookupTable; // A bone lookup table.
uint32 nTexLookup;
uint32 ofsTexLookup; // The same for textures.
uint32 nTexUnits; // possibly removed with cata?!
uint32 ofsTexUnits; // And texture units. Somewhere they have to be too.
uint32 nTransLookup;
uint32 ofsTransLookup; // Everything needs its lookup. Here are the transparencies.
uint32 nUVAnimLookup;
uint32 ofsUVAnimLookup;
G3D::AABox BoundingBox; // min/max( [1].z, 2.0277779f ) - 0.16f seems to be the maximum camera height
float BoundingSphereRadius;
G3D::AABox CollisionBox;
float CollisionSphereRadius;
uint32 nBoundingTriangles;
uint32 ofsBoundingTriangles; // Our bounding volumes. Similar structure like in the old ofsViews.
uint32 nBoundingVertices;
uint32 ofsBoundingVertices;
uint32 nBoundingNormals;
uint32 ofsBoundingNormals;
uint32 nAttachments;
uint32 ofsAttachments; // Attachments are for weapons etc.
uint32 nAttachLookup;
uint32 ofsAttachLookup; // Of course with a lookup.
uint32 nEvents;
uint32 ofsEvents; // Used for playing sounds when dying and a lot else.
uint32 nLights;
uint32 ofsLights; // Lights are mainly used in loginscreens but in wands and some doodads too.
uint32 nCameras; // Format of Cameras changed with version 271!
uint32 ofsCameras; // The cameras are present in most models for having a model in the Character-Tab.
uint32 nCameraLookup;
uint32 ofsCameraLookup; // And lookup-time again.
uint32 nRibbonEmitters;
uint32 ofsRibbonEmitters; // Things swirling around. See the CoT-entrance for light-trails.
uint32 nParticleEmitters;
uint32 ofsParticleEmitters; // Spells and weapons, doodads and loginscreens use them. Blood dripping of a blade? Particles.
uint32 nBlendMaps; // This has to deal with blending. Exists IFF (flags & 0x8) != 0. When set, textures blending is overriden by the associated array. See M2/WotLK#Blend_mode_overrides
uint32 ofsBlendMaps; // Same as above. Points to an array of uint16 of nBlendMaps entries -- From WoD information.};
};
struct M2Array
{
uint32_t number;
uint32 offset_elements;
};
struct M2Track
{
uint16_t interpolation_type;
uint16_t global_sequence;
M2Array timestamps;
M2Array values;
};
struct M2Camera
{
uint32_t type; // 0: portrait, 1: characterinfo; -1: else (flyby etc.); referenced backwards in the lookup table.
float fov; // No radians, no degrees. Multiply by 35 to get degrees.
float far_clip;
float near_clip;
M2Track positions; // How the camera's position moves. Should be 3*3 floats.
G3D::Vector3 position_base;
M2Track target_positions; // How the target moves. Should be 3*3 floats.
G3D::Vector3 target_position_base;
M2Track rolldata; // The camera can have some roll-effect. Its 0 to 2*Pi.
};
struct FlyByCamera
{
uint32 timeStamp;
G3D::Vector4 locations;
};
/// Interface class for common access
class DBCStorageBase
{

View File

@@ -719,13 +719,11 @@ struct ChrRacesEntry
struct CinematicCameraEntry
{
uint32 id; // 0 index
char const* filename; // 1
uint32 soundid; // 2 in SoundEntries.dbc or 0
float base_x; // 3
float base_y; // 4
float base_z; // 5
float base_o; // 6
uint32 ID; // 0
char const* Model; // 1 Model filename (translate .mdx to .m2)
uint32 SoundID; // 2 Sound ID (voiceover for cinematic)
DBCPosition3D Origin; // 3-5 Position in map used for basis for M2 co-ordinates
float OriginFacing; // 6 Orientation in map used for basis for M2 co-ordinates
};
struct CinematicSequencesEntry
@@ -1751,16 +1749,14 @@ struct SpellRadiusEntry
struct SpellRangeEntry
{
uint32 ID;
float minRangeHostile;
float minRangeFriend;
float maxRangeHostile;
float maxRangeFriend;
uint32 type;
//char const* Name[16]; // 7-23 unused
// 24 string flags, unused
//char const* Name2[16]; // 25-40 unused
// 41 string flags, unused
uint32 ID; // 0
float RangeMin[2]; // 1-2 [0] Hostile [1] Friendly
float RangeMax[2]; // 3-4 [0] Hostile [1] Friendly
uint32 Flags; // 5
// char const* DisplayName[16]; // 6-21
// uint32 DisplayName_lang_mask; // 22
// char const* DisplayNameShort[16]; // 23-38
// uint32 DisplayNameShort_lang_mask; // 39
};
struct SpellRuneCostEntry
@@ -2180,7 +2176,7 @@ struct WorldStateUI
// Structures not used for casting to loaded DBC data and not required then packing
struct MapDifficulty
{
MapDifficulty() {}
MapDifficulty() = default;
MapDifficulty(uint32 _resetTime, uint32 _maxPlayers, bool _hasErrorMessage) : resetTime(_resetTime), maxPlayers(_maxPlayers), hasErrorMessage(_hasErrorMessage) {}
uint32 resetTime{0};
@@ -2190,7 +2186,7 @@ struct MapDifficulty
struct TalentSpellPos
{
TalentSpellPos() {}
TalentSpellPos() = default;
TalentSpellPos(uint16 _talent_id, uint8 _rank) : talent_id(_talent_id), rank(_rank) {}
uint16 talent_id{0};
@@ -2201,7 +2197,7 @@ typedef std::map<uint32, TalentSpellPos> TalentSpellPosMap;
struct TaxiPathBySourceAndDestination
{
TaxiPathBySourceAndDestination() {}
TaxiPathBySourceAndDestination() = default;
TaxiPathBySourceAndDestination(uint32 _id, uint32 _price) : ID(_id), price(_price) {}
uint32 ID{0};

View File

@@ -65,7 +65,7 @@ public:
}
catch (boost::system::system_error const& err)
{
LOG_INFO("network", "Failed to initialize client's socket %s", err.what());
LOG_INFO("network", "Failed to initialize client's socket {}", err.what());
}
}
@@ -80,7 +80,7 @@ public:
_acceptor.open(_endpoint.protocol(), errorCode);
if (errorCode)
{
LOG_INFO("network", "Failed to open acceptor %s", errorCode.message().c_str());
LOG_INFO("network", "Failed to open acceptor {}", errorCode.message());
return false;
}
@@ -88,7 +88,7 @@ public:
_acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true), errorCode);
if (errorCode)
{
LOG_INFO("network", "Failed to set reuse_address option on acceptor %s", errorCode.message().c_str());
LOG_INFO("network", "Failed to set reuse_address option on acceptor {}", errorCode.message());
return false;
}
#endif
@@ -96,14 +96,14 @@ public:
_acceptor.bind(_endpoint, errorCode);
if (errorCode)
{
LOG_INFO("network", "Could not bind to %s:%u %s", _endpoint.address().to_string().c_str(), _endpoint.port(), errorCode.message().c_str());
LOG_INFO("network", "Could not bind to {}:{} {}", _endpoint.address().to_string(), _endpoint.port(), errorCode.message());
return false;
}
_acceptor.listen(ACORE_MAX_LISTEN_CONNECTIONS, errorCode);
if (errorCode)
{
LOG_INFO("network", "Failed to start listening on %s:%u %s", _endpoint.address().to_string().c_str(), _endpoint.port(), errorCode.message().c_str());
LOG_INFO("network", "Failed to start listening on {}:{} {}", _endpoint.address().to_string(), _endpoint.port(), errorCode.message());
return false;
}
@@ -145,7 +145,7 @@ void AsyncAcceptor::AsyncAccept()
}
catch (boost::system::system_error const& err)
{
LOG_INFO("network", "Failed to retrieve client's remote address %s", err.what());
LOG_INFO("network", "Failed to retrieve client's remote address {}", err.what());
}
}

View File

@@ -131,8 +131,8 @@ public:
_socket.shutdown(boost::asio::socket_base::shutdown_send, shutdownError);
if (shutdownError)
LOG_DEBUG("network", "Socket::CloseSocket: %s errored when shutting down socket: %i (%s)", GetRemoteIpAddress().to_string().c_str(),
shutdownError.value(), shutdownError.message().c_str());
LOG_DEBUG("network", "Socket::CloseSocket: {} errored when shutting down socket: {} ({})", GetRemoteIpAddress().to_string(),
shutdownError.value(), shutdownError.message());
OnClose();
}
@@ -170,8 +170,8 @@ protected:
_socket.set_option(tcp::no_delay(enable), err);
if (err)
LOG_DEBUG("network", "Socket::SetNoDelay: failed to set_option(boost::asio::ip::tcp::no_delay) for %s - %d (%s)",
GetRemoteIpAddress().to_string().c_str(), err.value(), err.message().c_str());
LOG_DEBUG("network", "Socket::SetNoDelay: failed to set_option(boost::asio::ip::tcp::no_delay) for {} - {} ({})",
GetRemoteIpAddress().to_string(), err.value(), err.message());
}
private:

View File

@@ -46,7 +46,7 @@ public:
}
catch (boost::system::system_error const& err)
{
LOG_ERROR("network", "Exception caught in SocketMgr.StartNetwork (%s:%u): %s", bindIp.c_str(), port, err.what());
LOG_ERROR("network", "Exception caught in SocketMgr.StartNetwork ({}:{}): {}", bindIp, port, err.what());
return false;
}
@@ -106,7 +106,7 @@ public:
}
catch (boost::system::system_error const& err)
{
LOG_WARN("network", "Failed to retrieve client's remote address %s", err.what());
LOG_WARN("network", "Failed to retrieve client's remote address {}", err.what());
}
}

View File

@@ -19,6 +19,7 @@
#include "Errors.h"
#include "Log.h"
#include "MessageBuffer.h"
#include "Timer.h"
#include "Util.h"
#include <ctime>
#include <sstream>
@@ -109,8 +110,8 @@ uint32 ByteBuffer::ReadPackedTime()
void ByteBuffer::append(uint8 const* src, size_t cnt)
{
ASSERT(src, "Attempted to put a NULL-pointer in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", _wpos, size());
ASSERT(cnt, "Attempted to put a zero-sized value in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", _wpos, size());
ASSERT(src, "Attempted to put a NULL-pointer in ByteBuffer (pos: {} size: {})", _wpos, size());
ASSERT(cnt, "Attempted to put a zero-sized value in ByteBuffer (pos: {} size: {})", _wpos, size());
ASSERT(size() < 10000000);
size_t const newSize = _wpos + cnt;
@@ -136,16 +137,15 @@ void ByteBuffer::append(uint8 const* src, size_t cnt)
void ByteBuffer::AppendPackedTime(time_t time)
{
tm lt;
localtime_r(&time, &lt);
tm lt = Acore::Time::TimeBreakdown(time);
append<uint32>((lt.tm_year - 100) << 24 | lt.tm_mon << 20 | (lt.tm_mday - 1) << 14 | lt.tm_wday << 11 | lt.tm_hour << 6 | lt.tm_min);
}
void ByteBuffer::put(size_t pos, uint8 const* src, size_t cnt)
{
ASSERT(pos + cnt <= size(), "Attempted to put value with size: " SZFMTD " in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", cnt, pos, size());
ASSERT(src, "Attempted to put a NULL-pointer in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", pos, size());
ASSERT(cnt, "Attempted to put a zero-sized value in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", pos, size());
ASSERT(pos + cnt <= size(), "Attempted to put value with size: {} in ByteBuffer (pos: {} size: {})", cnt, pos, size());
ASSERT(src, "Attempted to put a NULL-pointer in ByteBuffer (pos: {} size: {})", pos, size());
ASSERT(cnt, "Attempted to put a zero-sized value in ByteBuffer (pos: {} size: {})", pos, size());
std::memcpy(&_storage[pos], src, cnt);
}
@@ -163,7 +163,7 @@ void ByteBuffer::print_storage() const
o << " ";
LOG_TRACE("network.opcode.buffer", "%s", o.str().c_str());
LOG_TRACE("network.opcode.buffer", "{}", o.str());
}
void ByteBuffer::textlike() const
@@ -183,7 +183,7 @@ void ByteBuffer::textlike() const
o << " ";
LOG_TRACE("network.opcode.buffer", "%s", o.str().c_str());
LOG_TRACE("network.opcode.buffer", "{}", o.str());
}
void ByteBuffer::hexlike() const
@@ -218,5 +218,5 @@ void ByteBuffer::hexlike() const
o << " ";
LOG_TRACE("network.opcode.buffer", "%s", o.str().c_str());
LOG_TRACE("network.opcode.buffer", "{}", o.str());
}

View File

@@ -31,9 +31,9 @@ class MessageBuffer;
class AC_SHARED_API ByteBufferException : public std::exception
{
public:
~ByteBufferException() noexcept = default;
~ByteBufferException() noexcept override = default;
char const* what() const noexcept override { return msg_.c_str(); }
[[nodiscard]] char const* what() const noexcept override { return msg_.c_str(); }
protected:
std::string & message() noexcept { return msg_; }
@@ -47,7 +47,7 @@ class AC_SHARED_API ByteBufferPositionException : public ByteBufferException
public:
ByteBufferPositionException(bool add, size_t pos, size_t size, size_t valueSize);
~ByteBufferPositionException() noexcept = default;
~ByteBufferPositionException() noexcept override = default;
};
class AC_SHARED_API ByteBufferSourceException : public ByteBufferException
@@ -55,7 +55,7 @@ class AC_SHARED_API ByteBufferSourceException : public ByteBufferException
public:
ByteBufferSourceException(size_t pos, size_t size, size_t valueSize);
~ByteBufferSourceException() noexcept = default;
~ByteBufferSourceException() noexcept override = default;
};
class AC_SHARED_API ByteBufferInvalidValueException : public ByteBufferException
@@ -63,7 +63,7 @@ class AC_SHARED_API ByteBufferInvalidValueException : public ByteBufferException
public:
ByteBufferInvalidValueException(char const* type, char const* value);
~ByteBufferInvalidValueException() noexcept = default;
~ByteBufferInvalidValueException() noexcept override = default;
};
class AC_SHARED_API ByteBuffer
@@ -72,7 +72,7 @@ public:
constexpr static size_t DEFAULT_SIZE = 0x1000;
// constructor
ByteBuffer() : _rpos(0), _wpos(0)
ByteBuffer()
{
_storage.reserve(DEFAULT_SIZE);
}
@@ -355,7 +355,7 @@ public:
return r;
}
template <typename T> T read(size_t pos) const
template <typename T> [[nodiscard]] T read(size_t pos) const
{
if (pos + sizeof(T) > size())
{
@@ -528,7 +528,7 @@ public:
void hexlike() const;
protected:
size_t _rpos, _wpos;
size_t _rpos{0}, _wpos{0};
std::vector<uint8> _storage;
};

View File

@@ -36,10 +36,10 @@ enum RealmFlags
struct AC_SHARED_API RealmHandle
{
RealmHandle() : Realm(0) { }
RealmHandle() = default;
RealmHandle(uint32 index) : Realm(index) { }
uint32 Realm; // primary key in `realmlist` table
uint32 Realm{0}; // primary key in `realmlist` table
bool operator<(RealmHandle const& r) const
{
@@ -78,7 +78,7 @@ struct AC_SHARED_API Realm
AccountTypes AllowedSecurityLevel;
float PopulationLevel;
boost::asio::ip::tcp_endpoint GetAddressForClient(boost::asio::ip::address const& clientAddr) const;
[[nodiscard]] boost::asio::ip::tcp_endpoint GetAddressForClient(boost::asio::ip::address const& clientAddr) const;
};
#endif // Realm_h__

View File

@@ -24,8 +24,7 @@
#include "Util.h"
#include <boost/asio/ip/tcp.hpp>
RealmList::RealmList() :
_updateInterval(0) { }
RealmList::RealmList() : _updateInterval(0) { }
RealmList* RealmList::Instance()
{
@@ -60,10 +59,10 @@ void RealmList::LoadBuildInfo()
{
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();
build.MajorVersion = fields[0].Get<uint32>();
build.MinorVersion = fields[1].Get<uint32>();
build.BugfixVersion = fields[2].Get<uint32>();
std::string hotfixVersion = fields[3].Get<std::string>();
if (hotfixVersion.length() < build.HotfixVersion.size())
{
@@ -74,15 +73,15 @@ void RealmList::LoadBuildInfo()
std::fill(hotfixVersion.begin(), hotfixVersion.end(), '\0');
}
build.Build = fields[4].GetUInt32();
std::string windowsHash = fields[5].GetString();
build.Build = fields[4].Get<uint32>();
std::string windowsHash = fields[5].Get<std::string>();
if (windowsHash.length() == build.WindowsHash.size() * 2)
{
HexStrToByteArray(windowsHash, build.WindowsHash);
}
std::string macHash = fields[6].GetString();
std::string macHash = fields[6].Get<std::string>();
if (macHash.length() == build.MacHash.size() * 2)
{
@@ -155,35 +154,35 @@ void RealmList::UpdateRealms(boost::system::error_code const& error)
try
{
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();
uint32 realmId = fields[0].Get<uint32>();
std::string name = fields[1].Get<std::string>();
std::string externalAddressString = fields[2].Get<std::string>();
std::string localAddressString = fields[3].Get<std::string>();
std::string localSubmaskString = fields[4].Get<std::string>();
uint16 port = fields[5].Get<uint16>();
Optional<boost::asio::ip::tcp::endpoint> externalAddress = _resolver->Resolve(boost::asio::ip::tcp::v4(), externalAddressString, "");
if (!externalAddress)
{
LOG_ERROR("server.authserver", "Could not resolve address %s for realm \"%s\" id %u", externalAddressString.c_str(), name.c_str(), realmId);
LOG_ERROR("server.authserver", "Could not resolve address {} for realm \"{}\" id {}", externalAddressString, name, realmId);
continue;
}
Optional<boost::asio::ip::tcp::endpoint> localAddress = _resolver->Resolve(boost::asio::ip::tcp::v4(), localAddressString, "");
if (!localAddress)
{
LOG_ERROR("server.authserver", "Could not resolve localAddress %s for realm \"%s\" id %u", localAddressString.c_str(), name.c_str(), realmId);
LOG_ERROR("server.authserver", "Could not resolve localAddress {} for realm \"{}\" id {}", localAddressString, name, realmId);
continue;
}
Optional<boost::asio::ip::tcp::endpoint> localSubmask = _resolver->Resolve(boost::asio::ip::tcp::v4(), localSubmaskString, "");
if (!localSubmask)
{
LOG_ERROR("server.authserver", "Could not resolve localSubnetMask %s for realm \"%s\" id %u", localSubmaskString.c_str(), name.c_str(), realmId);
LOG_ERROR("server.authserver", "Could not resolve localSubnetMask {} for realm \"{}\" id {}", localSubmaskString, name, realmId);
continue;
}
uint8 icon = fields[6].GetUInt8();
uint8 icon = fields[6].Get<uint8>();
if (icon == REALM_TYPE_FFA_PVP)
{
@@ -195,11 +194,11 @@ void RealmList::UpdateRealms(boost::system::error_code const& error)
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();
RealmFlags flag = RealmFlags(fields[7].Get<uint8>());
uint8 timezone = fields[8].Get<uint8>();
uint8 allowedSecurityLevel = fields[9].Get<uint8>();
float pop = fields[10].Get<float>();
uint32 build = fields[11].Get<uint32>();
RealmHandle id{ realmId };
@@ -208,25 +207,25 @@ void RealmList::UpdateRealms(boost::system::error_code const& error)
if (!existingRealms.count(id))
{
LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), externalAddressString.c_str(), port);
LOG_INFO("server.authserver", "Added realm \"{}\" at {}:{}.", name, externalAddressString, port);
}
else
{
LOG_DEBUG("server.authserver", "Updating realm \"%s\" at %s:%u.", name.c_str(), externalAddressString.c_str(), port);
LOG_DEBUG("server.authserver", "Updating realm \"{}\" at {}:{}.", name, externalAddressString, port);
}
existingRealms.erase(id);
}
catch (std::exception const& ex)
{
LOG_ERROR("server.authserver", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what());
LOG_ERROR("server.authserver", "Realmlist::UpdateRealms has thrown an exception: {}", ex.what());
ABORT();
}
} while (result->NextRow());
}
for (auto itr = existingRealms.begin(); itr != existingRealms.end(); ++itr)
LOG_INFO("server.authserver", "Removed realm \"%s\".", itr->second.c_str());
LOG_INFO("server.authserver", "Removed realm \"{}\".", itr->second);
if (_updateInterval)
{

View File

@@ -52,10 +52,10 @@ public:
void Initialize(Acore::Asio::IoContext& ioContext, uint32 updateInterval);
void Close();
RealmMap const& GetRealms() const { return _realms; }
Realm const* GetRealm(RealmHandle const& id) const;
[[nodiscard]] RealmMap const& GetRealms() const { return _realms; }
[[nodiscard]] Realm const* GetRealm(RealmHandle const& id) const;
RealmBuildInfo const* GetBuildInfo(uint32 build) const;
[[nodiscard]] RealmBuildInfo const* GetBuildInfo(uint32 build) const;
private:
RealmList();
@@ -69,7 +69,7 @@ private:
std::vector<RealmBuildInfo> _builds;
RealmMap _realms;
uint32 _updateInterval;
uint32 _updateInterval{0};
std::unique_ptr<Acore::Asio::DeadlineTimer> _updateTimer;
std::unique_ptr<Acore::Asio::Resolver> _resolver;
};

View File

@@ -24,7 +24,6 @@
#include "Errors.h"
#include "Log.h"
#include "SharedDefines.h"
#include <functional>
#define SECRET_FLAG_FOR(key, val, server) server ## _ ## key = (val ## ull << (16*SERVER_PROCESS_ ## server))
#define SECRET_FLAG(key, val) SECRET_FLAG_ ## key = val, SECRET_FLAG_FOR(key, val, AUTHSERVER), SECRET_FLAG_FOR(key, val, WORLDSERVER)
@@ -42,7 +41,7 @@ struct SecretInfo
int bits;
ServerProcessTypes owner;
uint64 _flags;
uint16 flags() const { return static_cast<uint16>(_flags >> (16*THIS_SERVER_PROCESS)); }
[[nodiscard]] uint16 flags() const { return static_cast<uint16>(_flags >> (16*THIS_SERVER_PROCESS)); }
};
static constexpr SecretInfo secret_info[NUM_SECRETS] =
@@ -66,7 +65,7 @@ static Optional<BigNumber> GetHexFromConfig(char const* configKey, int bits)
BigNumber secret;
if (!secret.SetHexStr(str.c_str()))
{
LOG_FATAL("server.loading", "Invalid value for '%s' - specify a hexadecimal integer of up to %d bits with no prefix.", configKey, bits);
LOG_FATAL("server.loading", "Invalid value for '{}' - specify a hexadecimal integer of up to {} bits with no prefix.", configKey, bits);
ABORT();
}
@@ -74,7 +73,7 @@ static Optional<BigNumber> GetHexFromConfig(char const* configKey, int bits)
threshold <<= bits;
if (!((BigNumber(0) <= secret) && (secret < threshold)))
{
LOG_ERROR("server.loading", "Value for '%s' is out of bounds (should be an integer of up to %d bits with no prefix). Truncated to %d bits.", configKey, bits, bits);
LOG_ERROR("server.loading", "Value for '{}' is out of bounds (should be an integer of up to {} bits with no prefix). Truncated to {} bits.", configKey, bits, bits);
secret %= threshold;
}
ASSERT(((BigNumber(0) <= secret) && (secret < threshold)));
@@ -111,10 +110,10 @@ void SecretMgr::AttemptLoad(Secrets i, LogLevel errorLevel, std::unique_lock<std
Optional<std::string> oldDigest;
{
auto* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_SECRET_DIGEST);
stmt->setUInt32(0, i);
stmt->SetData(0, i);
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (result)
oldDigest = result->Fetch()->GetString();
oldDigest = result->Fetch()->Get<std::string>();
}
Optional<BigNumber> currentValue = GetHexFromConfig(info.configKey, info.bits);
@@ -128,9 +127,9 @@ void SecretMgr::AttemptLoad(Secrets i, LogLevel errorLevel, std::unique_lock<std
if (info.owner != THIS_SERVER_PROCESS)
{
if (currentValue)
LOG_MESSAGE_BODY("server.loading", errorLevel, "Invalid value for '%s' specified - this is not actually the secret being used in your auth DB.", info.configKey);
LOG_MESSAGE_BODY("server.loading", errorLevel, "Invalid value for '{}' specified - this is not actually the secret being used in your auth DB.", info.configKey);
else
LOG_MESSAGE_BODY("server.loading", errorLevel, "No value for '%s' specified - please specify the secret currently being used in your auth DB.", info.configKey);
LOG_MESSAGE_BODY("server.loading", errorLevel, "No value for '{}' specified - please specify the secret currently being used in your auth DB.", info.configKey);
_secrets[i].state = Secret::LOAD_FAILED;
return;
}
@@ -141,7 +140,7 @@ void SecretMgr::AttemptLoad(Secrets i, LogLevel errorLevel, std::unique_lock<std
oldSecret = GetHexFromConfig(info.oldKey, info.bits);
if (oldSecret && !Acore::Crypto::Argon2::Verify(oldSecret->AsHexStr(), *oldDigest))
{
LOG_MESSAGE_BODY("server.loading", errorLevel, "Invalid value for '%s' specified - this is not actually the secret previously used in your auth DB.", info.oldKey);
LOG_MESSAGE_BODY("server.loading", errorLevel, "Invalid value for '{}' specified - this is not actually the secret previously used in your auth DB.", info.oldKey);
_secrets[i].state = Secret::LOAD_FAILED;
return;
}
@@ -151,12 +150,12 @@ void SecretMgr::AttemptLoad(Secrets i, LogLevel errorLevel, std::unique_lock<std
Optional<std::string> error = AttemptTransition(Secrets(i), currentValue, oldSecret, static_cast<bool>(oldDigest));
if (error)
{
LOG_MESSAGE_BODY("server.loading", errorLevel, "Your value of '%s' changed, but we cannot transition your database to the new value:\n%s", info.configKey, error->c_str());
LOG_MESSAGE_BODY("server.loading", errorLevel, "Your value of '{}' changed, but we cannot transition your database to the new value:\n{}", info.configKey, error->c_str());
_secrets[i].state = Secret::LOAD_FAILED;
return;
}
LOG_INFO("server.loading", "Successfully transitioned database to new '%s' value.", info.configKey);
LOG_INFO("server.loading", "Successfully transitioned database to new '{}' value.", info.configKey);
}
if (currentValue)
@@ -183,8 +182,8 @@ Optional<std::string> SecretMgr::AttemptTransition(Secrets i, Optional<BigNumber
if (fields[1].IsNull())
continue;
uint32 id = fields[0].GetUInt32();
std::vector<uint8> totpSecret = fields[1].GetBinary();
uint32 id = fields[0].Get<uint32>();
std::vector<uint8> totpSecret = fields[1].Get<Binary>();
if (hadOldSecret)
{
@@ -200,8 +199,8 @@ Optional<std::string> SecretMgr::AttemptTransition(Secrets i, Optional<BigNumber
Acore::Crypto::AEEncryptWithRandomIV<Acore::Crypto::AES>(totpSecret, newSecret->ToByteArray<Acore::Crypto::AES::KEY_SIZE_BYTES>());
auto* updateStmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_TOTP_SECRET);
updateStmt->setBinary(0, totpSecret);
updateStmt->setUInt32(1, id);
updateStmt->SetData(0, totpSecret);
updateStmt->SetData(1, id);
trans->Append(updateStmt);
} while (result->NextRow());
@@ -214,7 +213,7 @@ Optional<std::string> SecretMgr::AttemptTransition(Secrets i, Optional<BigNumber
if (hadOldSecret)
{
auto* deleteStmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_SECRET_DIGEST);
deleteStmt->setUInt32(0, i);
deleteStmt->SetData(0, i);
trans->Append(deleteStmt);
}
@@ -227,8 +226,8 @@ Optional<std::string> SecretMgr::AttemptTransition(Secrets i, Optional<BigNumber
return std::string("Failed to hash new secret");
auto* insertStmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_SECRET_DIGEST);
insertStmt->setUInt32(0, i);
insertStmt->setString(1, *hash);
insertStmt->SetData(0, i);
insertStmt->SetData(1, *hash);
trans->Append(insertStmt);
}

View File

@@ -37,8 +37,8 @@ enum Secrets : uint32
class AC_SHARED_API SecretMgr
{
private:
SecretMgr() {}
~SecretMgr() {}
SecretMgr() = default;
~SecretMgr() = default;
public:
SecretMgr(SecretMgr const&) = delete;
@@ -50,7 +50,7 @@ public:
explicit operator bool() const { return (state == PRESENT); }
BigNumber const& operator*() const { return value; }
BigNumber const* operator->() const { return &value; }
bool IsAvailable() const { return (state != NOT_LOADED_YET) && (state != LOAD_FAILED); }
[[nodiscard]] bool IsAvailable() const { return (state != NOT_LOADED_YET) && (state != LOAD_FAILED); }
private:
std::mutex lock;
@@ -65,7 +65,7 @@ public:
private:
void AttemptLoad(Secrets i, LogLevel errorLevel, std::unique_lock<std::mutex> const&);
Optional<std::string> AttemptTransition(Secrets i, Optional<BigNumber> const& newSecret, Optional<BigNumber> const& oldSecret, bool hadOldSecret) const;
[[nodiscard]] Optional<std::string> AttemptTransition(Secrets i, Optional<BigNumber> const& newSecret, Optional<BigNumber> const& oldSecret, bool hadOldSecret) const;
std::array<Secret, NUM_SECRETS> _secrets;
};

View File

@@ -907,7 +907,7 @@ enum SpellEffects
SPELL_EFFECT_CREATE_ITEM_2 = 157,
SPELL_EFFECT_MILLING = 158,
SPELL_EFFECT_ALLOW_RENAME_PET = 159,
SPELL_EFFECT_160 = 160,
SPELL_EFFECT_FORCE_CAST_2 = 160,
SPELL_EFFECT_TALENT_SPEC_COUNT = 161,
SPELL_EFFECT_TALENT_SPEC_SELECT = 162,
SPELL_EFFECT_163 = 163,
@@ -3400,8 +3400,27 @@ enum ResponseCodes
CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x67
};
enum PvPTeamId
{
PVP_TEAM_HORDE = 0, // Battleground: Horde, Arena: Green
PVP_TEAM_ALLIANCE = 1, // Battleground: Alliance, Arena: Gold
PVP_TEAM_NEUTRAL = 2 // Battleground: Neutral, Arena: None
};
uint8 constexpr PVP_TEAMS_COUNT = 2;
inline PvPTeamId GetPvPTeamId(TeamId teamId)
{
return teamId == TEAM_ALLIANCE ? PVP_TEAM_ALLIANCE : PVP_TEAM_HORDE;
}
inline TeamId GetTeamId(PvPTeamId teamId)
{
return teamId == PVP_TEAM_ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE;
}
// indexes of BattlemasterList.dbc
enum BattlegroundTypeId
enum BattlegroundTypeId : uint8
{
BATTLEGROUND_TYPE_NONE = 0, // None
BATTLEGROUND_AV = 1, // Alterac Valley
@@ -3541,7 +3560,7 @@ enum DuelCompleteType
};
// handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time
enum BattlegroundQueueTypeId : uint32
enum BattlegroundQueueTypeId : uint8
{
BATTLEGROUND_QUEUE_NONE = 0,
BATTLEGROUND_QUEUE_AV = 1,

View File

@@ -159,7 +159,7 @@ AC_API_EXPORT EnumText EnumUtils<SpellAttr0>::ToString(SpellAttr0 value)
{
case SPELL_ATTR0_PROC_FAILURE_BURNS_CHARGE: return { "SPELL_ATTR0_PROC_FAILURE_BURNS_CHARGE", "Unknown attribute 0@Attr0", "" };
case SPELL_ATTR0_USES_RANGED_SLOT: return { "SPELL_ATTR0_USES_RANGED_SLOT", "Treat as ranged attack", "Use ammo, ranged attack range modifiers, ranged haste, etc." };
case SPELL_ATTR0_ON_NEXT_SWING_NO_DAMAGE: return { "SPELL_ATTR0_ON_NEXT_SWING_NO_DAMAGE", "On next melee (type 1)", "Both \042on next swing\042 attributes have identical handling in server & client" };
case SPELL_ATTR0_ON_NEXT_SWING_NO_DAMAGE: return { "SPELL_ATTR0_ON_NEXT_SWING_NO_DAMAGE", "On next melee (type 1)", R"(Both "on next swing" attributes have identical handling in server & client)" };
case SPELL_ATTR0_DO_NOT_LOG_IMMUNE_MISSES: return { "SPELL_ATTR0_DO_NOT_LOG_IMMUNE_MISSES", "Replenishment (client only)", "" };
case SPELL_ATTR0_IS_ABILITY: return { "SPELL_ATTR0_IS_ABILITY", "Treat as ability", "Cannot be reflected, not affected by cast speed modifiers, etc." };
case SPELL_ATTR0_IS_TRADESKILL: return { "SPELL_ATTR0_IS_TRADESKILL", "Trade skill recipe", "Displayed in recipe list, not affected by cast speed modifiers" };
@@ -167,7 +167,7 @@ AC_API_EXPORT EnumText EnumUtils<SpellAttr0>::ToString(SpellAttr0 value)
case SPELL_ATTR0_DO_NOT_DISPLAY: return { "SPELL_ATTR0_DO_NOT_DISPLAY", "Hidden in UI (client only)", "Not visible in spellbook or aura bar (Spellbook, Aura Icon, Combat Log)" };
case SPELL_ATTR0_DO_NOT_LOG: return { "SPELL_ATTR0_DO_NOT_LOG", "Hidden in combat log (client only)", "Spell will not appear in combat logs" };
case SPELL_ATTR0_HELD_ITEM_ONLY: return { "SPELL_ATTR0_HELD_ITEM_ONLY", "Auto-target mainhand item (client only)", "Client will automatically select main-hand item as cast target" };
case SPELL_ATTR0_ON_NEXT_SWING: return { "SPELL_ATTR0_ON_NEXT_SWING", "On next melee (type 2)", "Both \042on next swing\042 attributes have identical handling in server & client" };
case SPELL_ATTR0_ON_NEXT_SWING: return { "SPELL_ATTR0_ON_NEXT_SWING", "On next melee (type 2)", R"(Both "on next swing" attributes have identical handling in server & client)" };
case SPELL_ATTR0_WEARER_CASTS_PROC_TRIGGER: return { "SPELL_ATTR0_WEARER_CASTS_PROC_TRIGGER", "Unknown attribute 11@Attr0", "" };
case SPELL_ATTR0_SERVER_ONLY: return { "SPELL_ATTR0_SERVER_ONLY", "Only usable during daytime (unused)", "" };
case SPELL_ATTR0_ALLOW_ITEM_SPELL_IN_PVP: return { "SPELL_ATTR0_ALLOW_ITEM_SPELL_IN_PVP", "Only usable during nighttime (unused)", "" };
@@ -288,11 +288,11 @@ AC_API_EXPORT EnumText EnumUtils<SpellAttr1>::ToString(SpellAttr1 value)
{
case SPELL_ATTR1_DISMISS_PET_FIRST: return { "SPELL_ATTR1_DISMISS_PET_FIRST", "Dismiss Pet on cast", "Without this attribute, summoning spells will fail if caster already has a pet" };
case SPELL_ATTR1_USE_ALL_MANA: return { "SPELL_ATTR1_USE_ALL_MANA", "Drain all power", "Ignores listed power cost and drains entire pool instead" };
case SPELL_ATTR1_IS_CHANNELED: return { "SPELL_ATTR1_IS_CHANNELED", "Channeled (type 1)", "Both \042channeled\042 attributes have identical handling in server & client" };
case SPELL_ATTR1_IS_CHANNELED: return { "SPELL_ATTR1_IS_CHANNELED", "Channeled (type 1)", R"(Both "channeled" attributes have identical handling in server & client)" };
case SPELL_ATTR1_NO_REDIRECTION: return { "SPELL_ATTR1_NO_REDIRECTION", "Ignore redirection effects", "Spell will not be attracted by SPELL_MAGNET auras (Grounding Totem)" };
case SPELL_ATTR1_NO_SKILL_INCREASE: return { "SPELL_ATTR1_NO_SKILL_INCREASE", "Unknown attribute 4@Attr1", "stealth and whirlwind" };
case SPELL_ATTR1_ALLOW_WHILE_STEALTHED: return { "SPELL_ATTR1_ALLOW_WHILE_STEALTHED", "Does not break stealth", "" };
case SPELL_ATTR1_IS_SELF_CHANNELED: return { "SPELL_ATTR1_IS_SELF_CHANNELED", "Channeled (type 2)", "Both \042channeled\042 attributes have identical handling in server & client" };
case SPELL_ATTR1_IS_SELF_CHANNELED: return { "SPELL_ATTR1_IS_SELF_CHANNELED", "Channeled (type 2)", R"(Both "channeled" attributes have identical handling in server & client)" };
case SPELL_ATTR1_NO_REFLECTION: return { "SPELL_ATTR1_NO_REFLECTION", "Ignore reflection effects", "Spell will pierce through Spell Reflection and similar" };
case SPELL_ATTR1_ONLY_PEACEFUL_TARGETS: return { "SPELL_ATTR1_ONLY_PEACEFUL_TARGETS", "Target cannot be in combat", "" };
case SPELL_ATTR1_INITIATE_COMBAT: return { "SPELL_ATTR1_INITIATE_COMBAT", "Enables Auto-Attack (client only)", "Caster will begin auto-attacking the target on cast" };