Transcription ArgusCore lot 1 : 8 fixes anti-crash + anti-exploit
Anti-crash (adaptes a nos APIs) : - Spell: assert dur sur cible destination -> log+skip (a00b85b2) - SpellAuraEffects: DoT weapon-percent, caster nul -> tick a 0 (b456b7f7) - Battleground: PlayerScores.find sans garde -> continue si absent (e875f9f4) - VehicleHandler: 4x siege nul deref -> return (392466b1) - LootHandler: division par zero si liste vide -> return (e8196eed) Anti-exploit : - PetHandler: index action bar hors bornes (OOB write) + abandon reserve au proprietaire (fec060ab) - Guild: onglet de banque reserve au chef (2288f107) ; attribution de rang ne peut viser/donner un rang >= au sien (f94d82dc) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -860,9 +860,11 @@ void Battleground::EndBattleground(uint32 winner)
|
||||
|
||||
if (isBattleground() && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_STORE_STATISTICS_ENABLE))
|
||||
{
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PVPSTATS_PLAYER);
|
||||
BattlegroundScoreMap::const_iterator score = PlayerScores.find(player->GetGUID());
|
||||
if (score == PlayerScores.end()) // pas de score enregistre pour ce joueur (ArgusCore e875f9f4)
|
||||
continue;
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PVPSTATS_PLAYER);
|
||||
stmt->setUInt32(0, battlegroundId);
|
||||
stmt->setUInt64(1, player->GetGUID().GetCounter());
|
||||
stmt->setBool (2, team == winner);
|
||||
|
||||
@@ -1573,6 +1573,14 @@ void Guild::HandleSetNewGuildMaster(WorldSession* session, std::string const& na
|
||||
|
||||
void Guild::HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string const& name, std::string const& icon)
|
||||
{
|
||||
// seul le maitre de guilde peut renommer/re-iconer un onglet (comme l achat d onglet) (ArgusCore 2288f107)
|
||||
if (GetLeaderGUID() != session->GetPlayer()->GetGUID())
|
||||
{
|
||||
TC_LOG_ERROR("guild", "Guild::HandleSetBankTabInfo: Joueur %s sans droits de chef a tente de modifier l onglet %u.",
|
||||
session->GetPlayerInfo().c_str(), tabId);
|
||||
return;
|
||||
}
|
||||
|
||||
BankTab* tab = GetBankTab(tabId);
|
||||
if (!tab)
|
||||
{
|
||||
@@ -1934,6 +1942,17 @@ void Guild::HandleSetMemberRank(WorldSession* session, ObjectGuid targetGuid, Ob
|
||||
return;
|
||||
}
|
||||
|
||||
// avoir PROMOTE/DEMOTE ne permet pas d agir sur un membre de rang egal/superieur, ni d attribuer un rang egal/superieur au sien (ArgusCore f94d82dc)
|
||||
if (Member const* memberMe = GetMember(player->GetGUID()))
|
||||
{
|
||||
uint32 myRankId = memberMe->GetRankId();
|
||||
if (member->GetRankId() <= myRankId || rank <= myRankId)
|
||||
{
|
||||
SendCommandResult(session, type, ERR_GUILD_RANK_TOO_HIGH_S);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Player cannot promote himself
|
||||
if (member->IsSamePlayer(player->GetGUID()))
|
||||
{
|
||||
|
||||
@@ -222,6 +222,8 @@ void WorldSession::HandleLootMoneyOpcode(WorldPackets::Loot::LootMoney& /*packet
|
||||
playersNear.push_back(member);
|
||||
}
|
||||
|
||||
if (playersNear.empty()) // division par zero si personne a portee (ArgusCore e8196eed)
|
||||
return;
|
||||
uint32 goldPerPlayer = uint32((loot->gold) / (playersNear.size()));
|
||||
|
||||
for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i)
|
||||
|
||||
@@ -476,6 +476,9 @@ void WorldSession::HandlePetSetAction(WorldPackets::Pet::PetSetAction& packet)
|
||||
}
|
||||
|
||||
uint32 position = packet.Index;
|
||||
// position vient du client (CMSG_PET_SET_ACTION) ; PetActionBar est un tableau fixe -> ecriture hors bornes (ArgusCore fec060ab)
|
||||
if (position >= MAX_UNIT_ACTION_BAR_INDEX)
|
||||
return;
|
||||
uint32 actionData = packet.Action;
|
||||
|
||||
uint32 spell_id = UNIT_ACTION_BUTTON_ACTION(actionData);
|
||||
@@ -596,7 +599,7 @@ void WorldSession::HandlePetAbandon(WorldPackets::Pet::PetAbandon& packet)
|
||||
|
||||
// pet/charmed
|
||||
Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, packet.Pet);
|
||||
if (pet && pet->ToPet() && pet->ToPet()->getPetType() == HUNTER_PET)
|
||||
if (pet && pet->ToPet() && pet->ToPet()->getPetType() == HUNTER_PET && pet->GetOwnerGUID() == _player->GetGUID()) // proprietaire uniquement (ArgusCore fec060ab)
|
||||
{
|
||||
_player->RemovePet((Pet*)pet, PET_SAVE_AS_DELETED);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ void WorldSession::HandleRequestVehiclePrevSeat(WorldPackets::Vehicle::RequestVe
|
||||
return;
|
||||
|
||||
VehicleSeatEntry const* seat = GetPlayer()->GetVehicle()->GetSeatForPassenger(GetPlayer());
|
||||
if (!seat) // le joueur peut ne pas avoir de siege resolu (ArgusCore 392466b1)
|
||||
return;
|
||||
if (!seat->CanSwitchFromSeat())
|
||||
{
|
||||
TC_LOG_ERROR("network", "HandleRequestVehiclePrevSeat: %s tried to switch seats but current seatflags %u don't permit that.",
|
||||
@@ -59,6 +61,8 @@ void WorldSession::HandleRequestVehicleNextSeat(WorldPackets::Vehicle::RequestVe
|
||||
return;
|
||||
|
||||
VehicleSeatEntry const* seat = GetPlayer()->GetVehicle()->GetSeatForPassenger(GetPlayer());
|
||||
if (!seat) // le joueur peut ne pas avoir de siege resolu (ArgusCore 392466b1)
|
||||
return;
|
||||
if (!seat->CanSwitchFromSeat())
|
||||
{
|
||||
TC_LOG_ERROR("network", "HandleRequestVehicleNextSeat: %s tried to switch seats but current seatflags %u don't permit that.",
|
||||
@@ -76,6 +80,8 @@ void WorldSession::HandleMoveChangeVehicleSeats(WorldPackets::Vehicle::MoveChang
|
||||
return;
|
||||
|
||||
VehicleSeatEntry const* seat = GetPlayer()->GetVehicle()->GetSeatForPassenger(GetPlayer());
|
||||
if (!seat) // le joueur peut ne pas avoir de siege resolu (ArgusCore 392466b1)
|
||||
return;
|
||||
if (!seat->CanSwitchFromSeat())
|
||||
{
|
||||
TC_LOG_ERROR("network", "HandleMoveChangeVehicleSeats: %s tried to switch seats but current seatflags %u don't permit that.",
|
||||
@@ -105,6 +111,8 @@ void WorldSession::HandleRequestVehicleSwitchSeat(WorldPackets::Vehicle::Request
|
||||
return;
|
||||
|
||||
VehicleSeatEntry const* seat = GetPlayer()->GetVehicle()->GetSeatForPassenger(GetPlayer());
|
||||
if (!seat) // le joueur peut ne pas avoir de siege resolu (ArgusCore 392466b1)
|
||||
return;
|
||||
if (!seat->CanSwitchFromSeat())
|
||||
{
|
||||
TC_LOG_ERROR("network", "HandleRequestVehicleSwitchSeat: %s tried to switch seats but current seatflags %u don't permit that.",
|
||||
|
||||
@@ -5838,7 +5838,8 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
|
||||
{
|
||||
WeaponAttackType attackType = GetSpellInfo()->GetAttackType();
|
||||
|
||||
int32 weaponDamage = CalculatePct(caster->CalculateDamage(attackType, false, true), GetAmount());
|
||||
// le degat d arme exige un caster vivant ; s il a quitte la map, ce tick ne fait rien au lieu de crasher (ArgusCore b456b7f7)
|
||||
int32 weaponDamage = caster ? CalculatePct(caster->CalculateDamage(attackType, false, true), GetAmount()) : 0;
|
||||
|
||||
// Add melee damage bonuses (also check for negative)
|
||||
uint32 damageBonusDone = caster->MeleeDamageBonusDone(target, std::max(weaponDamage, 0), attackType, GetSpellInfo());
|
||||
|
||||
@@ -1533,7 +1533,12 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
|
||||
|
||||
void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
|
||||
{
|
||||
ASSERT(m_targets.GetObjectTarget() && "Spell::SelectImplicitTargetDestTargets - no explicit object target available!");
|
||||
// Un ligne spell_effect mal formee ne doit pas crasher le serveur : on log et on saute (ArgusCore a00b85b2)
|
||||
if (!m_targets.GetObjectTarget())
|
||||
{
|
||||
TC_LOG_ERROR("spells", "Spell::SelectImplicitTargetDestTargets: spell %u effect %u sans cible objet explicite; selection de destination ignoree.", m_spellInfo->Id, uint32(effIndex));
|
||||
return;
|
||||
}
|
||||
WorldObject* target = m_targets.GetObjectTarget();
|
||||
|
||||
SpellDestination dest(*target);
|
||||
|
||||
Reference in New Issue
Block a user