Description: When you install the patch (mpq) to the client, we are witnessing a critical bug with range.
Current behaviour: The maximum distance for use spells is increased in 2 times more than standard.
Steps to reproduce the problem:
Branch(es): 335
TC hash/commit: https://github.com/TrinityCore/TrinityCore/commit/f9582ed09d224265977ff62d25bdf0257b589af8
TDB version: 335.60 + updates.
Operating system: Ubuntu 14.04
SpellCastResult Spell::CheckCast(bool strict)
if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !m_caster->IsWithinLOS(x, y, z))
return SPELL_FAILED_LINE_OF_SIGHT;
}
+
+ // Test Anti-Rangehack (need test) may bug some triggers .. this is apply only for players. (i guess creatures will not use rangehack!? jk)
+ if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->GetMaxRange(m_spellInfo->IsPositive) + 2.0f > m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()))
+ return SPELL_FAILED_OUT_OF_RANGE;
// check pet presence
for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
Not work any ideas?
Confirm
Confirm
yeap, confirmed with Trinity Core version xx/07/2015 and currently rev.
@L30m4nc3r you can use ```diff
:)
@keader thank you :dancer: :)
Please forgive my ignorance, but does that patch-enUS-7.mpq
file belong in 3.3.5a (12340)?
My game client does not have any .mpq patch file # above 3, so is that file a Blizzard game client file?
If not, I would think your issue more or less falls outside the scope of TC, even if you want it fixed.
(Feel free to fill me in with info on this if I have missed your point about that .MPQ file.)
@tkrokli No this is not an official blizzard patch, your client must be modified to allow unsigned mpq files like this. This file alters the spell range for all spells. This will allow the user to cheat. So the server needs to check if the spell range is correct and not trust the client (the server should never trust the client). So i would argue that this falls into the scope of TC.
OK, good point. I forgot the part that when someone wants to hack the server, the hacker is the one who is in control of the game client file contents. Thanks for clarifying. Keep up the good work. :+1:
@tkrokli See the first post. Paragraph 1.
Download Patch
Yes, I got that part. I just did not see why the patch is relevant to the TC source before Nawuko told me.
can someone check the max possible range with rangehack (using .distance command)? the result should be around 9 yards
@joschiwald
The maximum I was able to 9.388755 yards
That's probably the server's movement/lag tolerance cutoff. IIRC there was something like that in the core.
no, melee range is calculated wrong in Unit::IsWithinMeleeRange, melee spells get 5 yard spell range + 2 yard caster melee range + 2 yard target melee range
@joschiwald
If i'm not mistaken, the maximum range is not same for melee spells and melee auto attacks.
melee auto attack:
a=unitA->combatReach;
b=unitB->combatReach;
if(a < 2)
a = 2;
if(b < 2)
b = 2;
maxRange= a + b + 1.0;
melee spell:
maxRange =unitA->combatReach + unitB->combatReach + 1.33333333;
if(maxRange <5.0)
maxRange = 5.0;
cf https://community.trinitycore.org/topic/12515-unambiguously-defining-auto-attack-and-spell-range/#comment-78179
EDIT: It looks like Spell::CheckRange
is also at the fault.
Maybe hack fix?
https://github.com/TrinityCore/TrinityCore/commit/4519be74a263acd17242fb4558b2bb3194c151a6
Confirm.
Any updates ?
There are also a lot other hack scripts that are installed via .mpq (for example, GCD hack).
What about ALSO check on player load if the player has other .mpq that are not the original ones?
Don't include size factor in range calculations if target is a player.
@robinsch so are you able to make a diff for it so we can test it please? ^^
Keep in mind that you might have to add a minimal factor due to player movement lag. Also use this to track hackers. If IsWithinMeleeRange is called with !includeSizeFactor and distancesq is greater (by a factor of 1.5f or something) the player is using some kind of hacks because the client already checks for range.
From f4911bac7d4a7107d6e4dbec484a64e03773f162 Mon Sep 17 00:00:00 2001
From: robinsch <[email protected]>
Date: Fri, 1 Jul 2016 11:21:49 +0200
---
src/server/game/Entities/Unit/Unit.cpp | 6 ++++--
src/server/game/Entities/Unit/Unit.h | 2 +-
src/server/game/Spells/Spell.cpp | 3 ++-
3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index a7f029d..7d17e2e 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -469,7 +469,7 @@ bool Unit::IsWithinCombatRange(const Unit* obj, float dist2compare) const
return distsq < maxdist * maxdist;
}
-bool Unit::IsWithinMeleeRange(const Unit* obj, float dist) const
+bool Unit::IsWithinMeleeRange(const Unit* obj, float dist, bool includeSizeFactor) const
{
if (!obj || !IsInMap(obj) || !InSamePhase(obj))
return false;
@@ -479,9 +479,11 @@ bool Unit::IsWithinMeleeRange(const Unit* obj, float dist) const
float dz = GetPositionZMinusOffset() - obj->GetPositionZMinusOffset();
float distsq = dx*dx + dy*dy + dz*dz;
- float sizefactor = GetMeleeReach() + obj->GetMeleeReach();
+ float sizefactor = includeSizeFactor ? GetMeleeReach() + obj->GetMeleeReach() : 0.0f;
float maxdist = dist + sizefactor;
return distsq < maxdist * maxdist;
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 275c3a6..8fb1a80 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1276,7 +1276,7 @@ class Unit : public WorldObject
float GetCombatReach() const { return m_floatValues[UNIT_FIELD_COMBATREACH]; }
float GetMeleeReach() const;
bool IsWithinCombatRange(const Unit* obj, float dist2compare) const;
- bool IsWithinMeleeRange(const Unit* obj, float dist = MELEE_RANGE) const;
+ bool IsWithinMeleeRange(const Unit* obj, float dist = MELEE_RANGE, bool includeSizeFactor = true) const;
void GetRandomContactPoint(const Unit* target, float &x, float &y, float &z, float distance2dMin, float distance2dMax) const;
uint32 m_extraAttacks;
bool m_canDualWield;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 3c2555d..095dca2 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -5786,8 +5786,9 @@ SpellCastResult Spell::CheckRange(bool strict)
{
if (range_type == SPELL_RANGE_MELEE)
{
+ bool includeSizeFactor = target->GetTypeId() == TYPEID_PLAYER ? false : true;
// Because of lag, we can not check too strictly here.
- if (!m_caster->IsWithinMeleeRange(target, max_range))
+ if (!m_caster->IsWithinMeleeRange(target, max_range, includeSizeFactor))
return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT;
}
else if (!m_caster->IsWithinCombatRange(target, max_range))
@robinsch Working, gonna report you how it goes with a populated server in some days, cause I don't understand what you mean with "you might have to add a minimal factor due to player movement lag".
Is it good for a PR?
@Raydor Not really, just wrote this quick, wasn't tested on a populated server. If you test this please check the above mentioned stuff. (For example, in PvP if players get "out of range" while client displays white icon".
@robinsch The spell indicator is still in white, thats checked by the client. Without the hack patch, the client displays red icon and with it, even with your fix, it displays white but the server returns Out of Range.
As you said, it's controlled by client (because they increase the spell range). There is nothing to fix.
That sucks a lot, there a lot of similar exploits produced by this "client preference".
There is also a fairly similar patch that reduces GCD of spells so you can cast spells with less GCD, its done the same way: modifying a DBC (spell.dbc) and adding it to an MPQ, but this is (imo) not related to this topic, but thats why I said if there is a way to check for different than original .mpq that a player has in his Data folder when he loads the game.
gcd is checked serverside.
Ok, gonna create bug report when I have a bit of time with that patch, but anyways you can do it easily, just modify for example warrior stances GCD in a custom spell.dbc and add it to a .mpq, then ingame you can use stances with 0,6 sec GCD (and CD) instead of 1 sec
EDIT: http://puu.sh/pMGZt/6efd63ec5f.jpg as you can see, it says 0,6 CD (I have the .mpq with the custom spell.dbc) and if you use a chronometer, its exactly 0,6. You can also notice it visually, the spell will recover faster from the CD than without the patch
EDIT 2: https://mega.nz/#!KtBxSKQb!nrUU6Qau2w4rtHieZFp6OSAtwWjXSvZsF20GrDgf64Y put this in your Data folder, you will need an enUS wow. Then spam warrior stances, you can compare with a friend at the same time and you will see you can change stances faster than him
@Raydor It's just visual, this got fixed years ago.
That is not fixed. 0.6s works for overpower and stances. Instead of say "that works/that not works", just try it, he shared the patch.
I created one myself too. It works on Warmane, all kind of private server and on my local machine.
@Romain-P It "semi" works because you are effectively reducing your GCD by server processing time + latency. This is not an exploit of any kind and is actually legitly implemented in cata and above clients (see: latency compensation setting). This is an age old simple trick used by many top players back in the day and there is nothing wrong with it. If you reduce the gcd on a spell by let's say 200ms, by the time it gets to the server and the server processes it, guess what? It's been 200ms already and the server will not reject the cast.
Most helpful comment
Keep in mind that you might have to add a minimal factor due to player movement lag. Also use this to track hackers. If IsWithinMeleeRange is called with !includeSizeFactor and distancesq is greater (by a factor of 1.5f or something) the player is using some kind of hacks because the client already checks for range.