Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ed6eea2f43 | |||
| a9c5cacec8 | |||
| 146f02f046 | |||
| a2c532b676 | |||
| 9b7fb4dfdb | |||
| d9173eca3e | |||
| 36cde9a0bd | |||
| 8af2ddc596 | |||
| 316e886869 | |||
| a87eb41eac | |||
| a9fa07aab5 | |||
| 4c51bb778d | |||
| d0c3a62be2 |
@@ -9,3 +9,5 @@ BUILD_JOBS=2
|
||||
PARTY_BOT_MAX_BOTS=4
|
||||
# Fill battleground queues with bots when a real player queues.
|
||||
BATTLE_BOT_AUTO_JOIN=0
|
||||
# Quest item drop chance multiplier (1 = stock vanilla).
|
||||
RATE_DROP_ITEM_QUEST=2
|
||||
|
||||
@@ -69,6 +69,7 @@ services:
|
||||
TZ: Europe/Moscow
|
||||
PARTY_BOT_MAX_BOTS: ${PARTY_BOT_MAX_BOTS:-4}
|
||||
BATTLE_BOT_AUTO_JOIN: ${BATTLE_BOT_AUTO_JOIN:-0}
|
||||
RATE_DROP_ITEM_QUEST: ${RATE_DROP_ITEM_QUEST:-2}
|
||||
MOONWELL_VOICE_ENABLE: ${MOONWELL_VOICE_ENABLE:-0}
|
||||
MOONWELL_VOICE_ADDRESS: ${MOONWELL_VOICE_ADDRESS:-}
|
||||
MOONWELL_VOICE_FEED: voice-relay:3726
|
||||
|
||||
@@ -32,6 +32,10 @@ else:
|
||||
values[key] = str(value)
|
||||
values.update({"DataDir": '"/data"', "HonorDir": '"/var/log/vmangos"', "RealmID": "1", "RealmZone": "12", "DeclinedNames": "1", "Console.Enable": "0", "Ra.Enable": "0", "SOAP.Enabled": "0", "PlayerSave.Interval": "300000"})
|
||||
values.update({"Warden.WinEnabled": "0", "Warden.OSXEnabled": "0"})
|
||||
quest_drop = os.environ.get("RATE_DROP_ITEM_QUEST", "2")
|
||||
if not re.fullmatch(r"[0-9]{1,2}(\.[0-9]{1,2})?", quest_drop) or not 0 < float(quest_drop) <= 10:
|
||||
raise SystemExit("Invalid RATE_DROP_ITEM_QUEST")
|
||||
values["Rate.Drop.Item.Quest"] = quest_drop
|
||||
console = os.environ.get("CONSOLE_ENABLE", "0")
|
||||
if console not in ("0", "1"):
|
||||
raise SystemExit("Invalid CONSOLE_ENABLE")
|
||||
|
||||
@@ -947,6 +947,9 @@ bool Group::CountRollVote(ObjectGuid const& playerGUID, Rolls::iterator& rollI,
|
||||
if (itr == roll->playerVote.end())
|
||||
return true; // result used for need iterator ++, so avoid for end of list
|
||||
|
||||
if (itr->second != ROLL_NOT_EMITED_YET)
|
||||
return false; // player already rolled for this loot!
|
||||
|
||||
if (Loot* pLoot = roll->getLoot())
|
||||
if (pLoot->items.empty())
|
||||
return false;
|
||||
|
||||
@@ -270,7 +270,10 @@ bool LootStoreItem::Roll(bool rate, float chanceMod) const
|
||||
|
||||
ItemPrototype const* pProto = sObjectMgr.GetItemPrototype(itemid);
|
||||
|
||||
float qualityModifier = pProto && rate ? sWorld.getConfig(qualityToRate[pProto->Quality]) : 1.0f;
|
||||
// MoonWell: a quest drop takes the quest rate in place of its quality's.
|
||||
float qualityModifier = !rate ? 1.0f
|
||||
: needs_quest ? sWorld.getConfig(CONFIG_FLOAT_RATE_DROP_ITEM_QUEST)
|
||||
: pProto ? sWorld.getConfig(qualityToRate[pProto->Quality]) : 1.0f;
|
||||
|
||||
return roll_chance_f(chance * chanceMod * qualityModifier);
|
||||
}
|
||||
|
||||
@@ -701,7 +701,8 @@ uint32 MapManager::GetContinentInstanceId(uint32 mapId, float x, float y, bool*
|
||||
-10670.61f, -1692.51f,
|
||||
-10908.48f, -1563.87f,
|
||||
-13006.40f, -1622.80f,
|
||||
-12863.23f, -4798.42f
|
||||
-12863.23f, -4798.42f,
|
||||
-12863.23f, -5855.58f
|
||||
};
|
||||
static float const stormwindAreaSouthLimit[] = {
|
||||
-8725.337891f, 3535.624023f,
|
||||
|
||||
@@ -9590,6 +9590,12 @@ uint8 ObjectMgr::CheckPlayerName(std::string const& name, bool create)
|
||||
if (wname.size() < minName)
|
||||
return CHAR_NAME_TOO_SHORT;
|
||||
|
||||
for (size_t i = 2; i < wname.size(); ++i)
|
||||
{
|
||||
if (wname[i] == wname[i - 1] && wname[i] == wname[i - 2])
|
||||
return CHAR_NAME_THREE_CONSECUTIVE;
|
||||
}
|
||||
|
||||
uint32 strictMask = sWorld.getConfig(CONFIG_UINT32_STRICT_PLAYER_NAMES);
|
||||
if (!isValidString(wname, strictMask, false, create))
|
||||
return CHAR_NAME_MIXED_LANGUAGES;
|
||||
|
||||
@@ -22770,7 +22770,7 @@ void Log::Player(WorldSession const* session, LogType logType, char const* subTy
|
||||
// Player logs should never go to the console
|
||||
}
|
||||
|
||||
void Log:: Player(uint32 accountId, LogType logType, LogLevel logLevel, char const* format, ...)
|
||||
void Log::Player(uint32 accountId, LogType logType, LogLevel logLevel, char const* format, ...)
|
||||
{
|
||||
if (logType >= LOG_TYPE_MAX || logType < 0)
|
||||
return;
|
||||
|
||||
@@ -2953,7 +2953,7 @@ void Spell::EffectTeleUnitsFaceCaster(SpellEffectIndex effIdx)
|
||||
m_caster->GetClosePoint(fx, fy, fz, unitTarget->GetObjectBoundingRadius(), dis);
|
||||
}
|
||||
|
||||
unitTarget->NearTeleportTo(fx, fy, fz, -m_caster->GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget == m_caster ? TELE_TO_SPELL : 0));
|
||||
unitTarget->NearTeleportTo(fx, fy, fz, m_caster->GetAngle(fx, fy) - M_PI_F, TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget == m_caster ? TELE_TO_SPELL : 0));
|
||||
}
|
||||
|
||||
void Spell::EffectLearnSkill(SpellEffectIndex effIdx)
|
||||
|
||||
@@ -503,6 +503,7 @@ void World::LoadConfigSettings(bool reload)
|
||||
setConfigPos(CONFIG_FLOAT_RATE_DROP_ITEM_LEGENDARY, "Rate.Drop.Item.Legendary", 1.0f);
|
||||
setConfigPos(CONFIG_FLOAT_RATE_DROP_ITEM_ARTIFACT, "Rate.Drop.Item.Artifact", 1.0f);
|
||||
setConfigPos(CONFIG_FLOAT_RATE_DROP_ITEM_REFERENCED, "Rate.Drop.Item.Referenced", 1.0f);
|
||||
setConfigPos(CONFIG_FLOAT_RATE_DROP_ITEM_QUEST, "Rate.Drop.Item.Quest", 1.0f);
|
||||
setConfigPos(CONFIG_FLOAT_RATE_DROP_MONEY, "Rate.Drop.Money", 1.0f);
|
||||
setConfig(CONFIG_FLOAT_RATE_XP_KILL, "Rate.XP.Kill", 1.0f);
|
||||
setConfig(CONFIG_FLOAT_RATE_XP_KILL_ELITE, "Rate.XP.Kill.Elite", 1.0f);
|
||||
|
||||
@@ -408,6 +408,7 @@ enum eConfigFloatValues
|
||||
CONFIG_FLOAT_RATE_DROP_ITEM_LEGENDARY,
|
||||
CONFIG_FLOAT_RATE_DROP_ITEM_ARTIFACT,
|
||||
CONFIG_FLOAT_RATE_DROP_ITEM_REFERENCED,
|
||||
CONFIG_FLOAT_RATE_DROP_ITEM_QUEST,
|
||||
CONFIG_FLOAT_RATE_DROP_MONEY,
|
||||
CONFIG_FLOAT_RATE_XP_KILL,
|
||||
CONFIG_FLOAT_RATE_XP_KILL_ELITE,
|
||||
|
||||
@@ -2626,8 +2626,9 @@ Visibility.ForceActiveObjects = 1
|
||||
# Rate.Drop.Item.Legendary
|
||||
# Rate.Drop.Item.Artifact
|
||||
# Rate.Drop.Item.Referenced
|
||||
# Rate.Drop.Item.Quest
|
||||
# Rate.Drop.Money
|
||||
# Drop rates (items by quality and money)
|
||||
# Drop rates (items by quality, quest items in place of their quality, and money)
|
||||
# Default: 1
|
||||
#
|
||||
# Rate.XP.Kill
|
||||
@@ -2805,6 +2806,7 @@ Rate.Drop.Item.Epic = 1
|
||||
Rate.Drop.Item.Legendary = 1
|
||||
Rate.Drop.Item.Artifact = 1
|
||||
Rate.Drop.Item.Referenced = 1
|
||||
Rate.Drop.Item.Quest = 1
|
||||
Rate.Drop.Money = 1
|
||||
Rate.XP.Kill = 1
|
||||
Rate.XP.Kill.Elite = 1
|
||||
|
||||
+37
-20
@@ -171,7 +171,7 @@ void AuthSocket::DoRecvIncomingData()
|
||||
|
||||
std::shared_ptr<ByteBuffer> AuthSocket::GenerateLogonProofResponse(Crypto::Hash::SHA1::Digest const& shaDigest)
|
||||
{
|
||||
std::shared_ptr<ByteBuffer> pkt(new ByteBuffer());
|
||||
auto pkt = std::make_shared<ByteBuffer>();
|
||||
|
||||
if (m_build < 6299) // before version 2.0.3 (exclusive)
|
||||
{
|
||||
@@ -587,7 +587,7 @@ void AuthSocket::_HandleLogonProof()
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<PINData> pinData(new PINData());
|
||||
auto pinData = std::make_shared<PINData>();
|
||||
self->m_socket.Read((char*) pinData.get(), sizeof(PINData), [self, lp, pinData](IO::NetworkError const& error, size_t)
|
||||
{
|
||||
self->_HandleLogonProof__PostRecv(lp, pinData);
|
||||
@@ -620,7 +620,7 @@ void AuthSocket::_HandleLogonProof__PostRecv_HandleInvalidVersion(std::shared_pt
|
||||
if (m_pendingPatchFile == nullptr)
|
||||
{
|
||||
// no patch found
|
||||
std::shared_ptr<ByteBuffer> pkt(new ByteBuffer());
|
||||
auto pkt = std::make_shared<ByteBuffer>();
|
||||
*pkt << (uint8) CMD_AUTH_LOGON_CHALLENGE;
|
||||
*pkt << (uint8) 0x00;
|
||||
*pkt << (uint8) WOW_FAIL_VERSION_INVALID;
|
||||
@@ -643,7 +643,7 @@ void AuthSocket::_HandleLogonProof__PostRecv_HandleInvalidVersion(std::shared_pt
|
||||
std::string wowClientPathType = "Patch"; // Must be patch "Patch"
|
||||
MANGOS_ASSERT(wowClientPathType.size() <= 255); // Filename must fit inside a byte
|
||||
|
||||
std::shared_ptr<ByteBuffer> pkt(new ByteBuffer());
|
||||
auto pkt = std::make_shared<ByteBuffer>();
|
||||
|
||||
// packet 1
|
||||
*pkt << (uint8) CMD_AUTH_LOGON_PROOF;
|
||||
@@ -714,7 +714,7 @@ void AuthSocket::_HandleLogonProof__PostRecv(std::shared_ptr<sAuthLogonProof_C c
|
||||
pinResult = VerifyPinData(std::stoi(m_securityInfo), *pinData);
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
sLog.Out(LOG_BASIC, LOG_LVL_ERROR, "[AuthChallenge] Account '%s' failed to parse FIXED_PIN from security info: %s", m_login.c_str(), e.what());
|
||||
pinResult = false;
|
||||
@@ -723,15 +723,31 @@ void AuthSocket::_HandleLogonProof__PostRecv(std::shared_ptr<sAuthLogonProof_C c
|
||||
}
|
||||
else if ((m_lockFlags & TOTP) == TOTP)
|
||||
{
|
||||
for (int i = -2; i != 2; ++i)
|
||||
try
|
||||
{
|
||||
auto pin = GenerateTotpPin(m_securityInfo, i);
|
||||
if (m_securityInfo.empty())
|
||||
{
|
||||
sLog.Out(LOG_BASIC, LOG_LVL_DEBUG, "[AuthChallenge] Account '%s' has empty security info for TOTP", m_login.c_str());
|
||||
pinResult = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = -2; i != 2; ++i)
|
||||
{
|
||||
auto pin = GenerateTotpPin(m_securityInfo, i);
|
||||
|
||||
if (pin == uint32(-1))
|
||||
break;
|
||||
if (pin == uint32(-1))
|
||||
break;
|
||||
|
||||
if ((pinResult = VerifyPinData(pin, *pinData)))
|
||||
break;
|
||||
if ((pinResult = VerifyPinData(pin, *pinData)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
sLog.Out(LOG_BASIC, LOG_LVL_ERROR, "[AuthChallenge] Account '%s' failed to parse TOTP from security info: %s", m_login.c_str(), e.what());
|
||||
pinResult = false;
|
||||
}
|
||||
}
|
||||
else if (m_geoUnlockPIN)
|
||||
@@ -746,13 +762,14 @@ void AuthSocket::_HandleLogonProof__PostRecv(std::shared_ptr<sAuthLogonProof_C c
|
||||
}
|
||||
|
||||
// Check if SRP6 results match (password is correct), else send an error
|
||||
if (!srp.Proof(lp->M1, 20) && pinResult)
|
||||
bool const passwordResult = !srp.Proof(lp->M1, 20);
|
||||
if (passwordResult && pinResult)
|
||||
{
|
||||
if (!VerifyVersion(lp->A, sizeof(lp->A), lp->crc_hash, false))
|
||||
{
|
||||
sLog.Out(LOG_BASIC, LOG_LVL_BASIC, "[AuthChallenge] Account %s tried to login with modified client!", m_login.c_str());
|
||||
|
||||
std::shared_ptr<ByteBuffer> pkt(new ByteBuffer());
|
||||
auto pkt = std::make_shared<ByteBuffer>();
|
||||
*pkt << (uint8) CMD_AUTH_LOGON_PROOF;
|
||||
*pkt << (uint8) WOW_FAIL_VERSION_INVALID;
|
||||
m_socket.Write(std::move(pkt), [self = shared_from_this()](IO::NetworkError const& error)
|
||||
@@ -781,7 +798,7 @@ void AuthSocket::_HandleLogonProof__PostRecv(std::shared_ptr<sAuthLogonProof_C c
|
||||
{
|
||||
sLog.Out(LOG_BASIC, LOG_LVL_ERROR, "Unable to write geolock PIN for %s - account has not been locked", m_safelogin.c_str());
|
||||
|
||||
std::shared_ptr<ByteBuffer> pkt(new ByteBuffer());
|
||||
auto pkt = std::make_shared<ByteBuffer>();
|
||||
*pkt << (uint8) CMD_AUTH_LOGON_PROOF;
|
||||
*pkt << (uint8) WOW_FAIL_DB_BUSY;
|
||||
m_socket.Write(std::move(pkt), [self = shared_from_this()](IO::NetworkError const& error)
|
||||
@@ -815,7 +832,7 @@ void AuthSocket::_HandleLogonProof__PostRecv(std::shared_ptr<sAuthLogonProof_C c
|
||||
}
|
||||
#endif
|
||||
|
||||
std::shared_ptr<ByteBuffer> pkt(new ByteBuffer());
|
||||
auto pkt = std::make_shared<ByteBuffer>();
|
||||
*pkt << (uint8) CMD_AUTH_LOGON_PROOF;
|
||||
*pkt << (uint8) WOW_FAIL_PARENTCONTROL;
|
||||
m_socket.Write(std::move(pkt), [self = shared_from_this()](IO::NetworkError const& error)
|
||||
@@ -888,12 +905,12 @@ void AuthSocket::_HandleLogonProof__PostRecv(std::shared_ptr<sAuthLogonProof_C c
|
||||
else
|
||||
{
|
||||
// We are here because the password was incorrect
|
||||
sLog.Out(LOG_BASIC, LOG_LVL_BASIC, "[AuthChallenge] Account '%s' using IP '%s' tried to login with wrong password!", m_login.c_str (), GetRemoteIpString().c_str());
|
||||
sLog.Out(LOG_BASIC, LOG_LVL_BASIC, "[AuthChallenge] Account '%s' using IP '%s' tried to login with wrong %s!", m_login.c_str (), GetRemoteIpString().c_str(), (passwordResult ? "pin" : "password"));
|
||||
|
||||
// Record the failure for the in-memory brute-force guard.
|
||||
RecordWrongPasswordAttempt(GetRemoteIpString());
|
||||
|
||||
std::shared_ptr<ByteBuffer> pkt(new ByteBuffer());
|
||||
auto pkt = std::make_shared<ByteBuffer>();
|
||||
*pkt << (uint8) CMD_AUTH_LOGON_PROOF;
|
||||
*pkt << (uint8) WOW_FAIL_UNKNOWN_ACCOUNT;
|
||||
if (m_build > 6005) // > 1.12.2
|
||||
@@ -953,7 +970,7 @@ void AuthSocket::_HandleReconnectProof()
|
||||
m_status = STATUS_INVALID;
|
||||
|
||||
// Read the packet
|
||||
std::shared_ptr<AUTH_RECONNECT_PROOF_C> lp(new AUTH_RECONNECT_PROOF_C());
|
||||
auto lp = std::make_shared<AUTH_RECONNECT_PROOF_C>();
|
||||
m_socket.Read((char*) lp.get(), sizeof(AUTH_RECONNECT_PROOF_C), [self = shared_from_this(), lp](IO::NetworkError const& error, size_t)
|
||||
{
|
||||
if (error)
|
||||
@@ -1056,7 +1073,7 @@ void AuthSocket::_HandleRealmList()
|
||||
ByteBuffer realmlistBuffer;
|
||||
self->LoadRealmlistAndWriteIntoBuffer(realmlistBuffer);
|
||||
|
||||
std::shared_ptr<ByteBuffer> pkt(new ByteBuffer());
|
||||
auto pkt = std::make_shared<ByteBuffer>();
|
||||
*pkt << (uint8) CMD_REALM_LIST;
|
||||
*pkt << (uint16)realmlistBuffer.size();
|
||||
pkt->append(realmlistBuffer);
|
||||
@@ -1370,7 +1387,7 @@ void AuthSocket::InitAndHandOverControlToPatchHandler()
|
||||
{
|
||||
MANGOS_ASSERT(m_pendingPatchFile);
|
||||
|
||||
std::shared_ptr<XFER_DATA_CHUNK> rawChunk(new XFER_DATA_CHUNK());
|
||||
auto rawChunk = std::make_shared<XFER_DATA_CHUNK>();
|
||||
rawChunk->cmd = CMD_XFER_DATA;
|
||||
|
||||
RepeatInternalXferLoop(rawChunk);
|
||||
|
||||
@@ -952,7 +952,7 @@ bool GossipHello_ProfessionNPC(Player* player, Creature* creature)
|
||||
|
||||
void CompleteLearnProfession(Player *pPlayer, Creature *pCreature, SkillType skill)
|
||||
{
|
||||
if (pPlayer->GetFreePrimaryProfessionPoints() == 0 && !(skill == SKILL_COOKING || skill == SKILL_FIRST_AID))
|
||||
if (pPlayer->GetFreePrimaryProfessionPoints() == 0 && !(skill == SKILL_COOKING || skill == SKILL_FIRST_AID || skill == SKILL_FISHING))
|
||||
{
|
||||
pPlayer->GetSession()->SendNotification("You already know two primary professions.");
|
||||
}
|
||||
|
||||
@@ -859,7 +859,7 @@ struct npc_rabid_thistle_bearAI : public FollowerAI
|
||||
|
||||
void StartFollowing(Player* pPlayer)
|
||||
{
|
||||
Captured_Timer = 300000;
|
||||
Captured_Timer = 500000;
|
||||
StartFollow(pPlayer);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user