Skip to content

Commit

Permalink
Arena anticheat system
Browse files Browse the repository at this point in the history
  • Loading branch information
Yelvann committed Feb 13, 2014
1 parent b9074f3 commit 92c4b4e
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 33 deletions.
113 changes: 80 additions & 33 deletions src/server/game/Battlegrounds/Battleground.cpp
Expand Up @@ -715,6 +715,42 @@ void Battleground::UpdateWorldStateForPlayer(uint32 field, uint32 value, Player*
player->SendDirectMessage(&data);
}

bool Battleground::CheckCheatArena(uint32 winTeam)
{
uint8 counted = 0; // Player did nothing?, nor heal nor dmg ... weird...
uint32 maxHealthWinner = 1;
uint32 dmgLoser = 0;

if (!GetPlayersCountByTeam(ALLIANCE) || !GetPlayersCountByTeam(HORDE))
return false;

for (Battleground::BattlegroundScoreMap::const_iterator itr = GetPlayerScoresBegin(); itr != GetPlayerScoresEnd(); ++itr)
{
if (!itr->second->DamageDone && !itr->second->HealingDone) ++counted;
else if (Player* player = ObjectAccessor::FindPlayer(itr->first))
{
if ((player->GetArenaTeamId(m_ArenaType == 5 ? 2 : m_ArenaType == 3) == winTeam)) maxHealthWinner += player->GetMaxHealth();
else dmgLoser += itr->second->DamageDone;
}
}

float factorLooser = dmgLoser * 100 / maxHealthWinner; // did looser team gave fight?
float factor = (counted + 0.0) / GetPlayersSize();

switch (m_ArenaType)
{
case 2: // Arena 2v2. Half players (or more) done 0 dmg, 0 heal || At least looser team did 10% dmg [Default values]?
return factor >= sWorld->getFloatConfig(CONFIG_ARENA_CHECK_CHEATERS_2v2) || factorLooser <= sWorld->getIntConfig(CONFIG_ARENA_CHECK_CHEATERS_MIN_DMG_2v2);
case 3:
return factor >= sWorld->getFloatConfig(CONFIG_ARENA_CHECK_CHEATERS_3v3) || factorLooser <= sWorld->getIntConfig(CONFIG_ARENA_CHECK_CHEATERS_MIN_DMG_3v3);
case 5:
return factor >= sWorld->getFloatConfig(CONFIG_ARENA_CHECK_CHEATERS_5v5) || factorLooser <= sWorld->getIntConfig(CONFIG_ARENA_CHECK_CHEATERS_MIN_DMG_5v5);
default:
return false;
}
return false;
}

void Battleground::EndBattleground(uint32 winner)
{
RemoveFromBGFreeSlotQueue();
Expand Down Expand Up @@ -763,48 +799,59 @@ void Battleground::EndBattleground(uint32 winner)
{
winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(winner));
loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(winner)));

if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam)
if (sWorld->getBoolConfig(CONFIG_ARENA_CHECK_CHEATERS) && CheckCheatArena(GetArenaTeamIdForTeam(winner)))
{
if (winner != WINNER_NONE)
if (!sWorld->getBoolConfig(CONFIG_ARENA_CHECK_CHEATERS_ONLYLOG))
{
loserTeamRating = loserArenaTeam->GetRating();
loserMatchmakerRating = GetArenaMatchmakerRating(GetOtherTeam(winner));
winnerTeamRating = winnerArenaTeam->GetRating();
winnerMatchmakerRating = GetArenaMatchmakerRating(winner);
winnerMatchmakerChange = winnerArenaTeam->WonAgainst(winnerMatchmakerRating, loserMatchmakerRating, winnerChange);
loserMatchmakerChange = loserArenaTeam->LostAgainst(loserMatchmakerRating, winnerMatchmakerRating, loserChange);
TC_LOG_DEBUG("bg.arena", "match Type: %u --- Winner: old rating: %u, rating gain: %d, old MMR: %u, MMR gain: %d --- Loser: old rating: %u, rating loss: %d, old MMR: %u, MMR loss: %d ---", m_ArenaType, winnerTeamRating, winnerChange, winnerMatchmakerRating,
winnerMatchmakerChange, loserTeamRating, loserChange, loserMatchmakerRating, loserMatchmakerChange);
SetArenaMatchmakerRating(winner, winnerMatchmakerRating + winnerMatchmakerChange);
SetArenaMatchmakerRating(GetOtherTeam(winner), loserMatchmakerRating + loserMatchmakerChange);
SetArenaTeamRatingChangeForTeam(winner, winnerChange);
SetArenaTeamRatingChangeForTeam(GetOtherTeam(winner), loserChange);
TC_LOG_DEBUG("bg.arena", "Arena match Type: %u for Team1Id: %u - Team2Id: %u ended. WinnerTeamId: %u. Winner rating: +%d, Loser rating: %d", m_ArenaType, m_ArenaTeamIds[TEAM_ALLIANCE], m_ArenaTeamIds[TEAM_HORDE], winnerArenaTeam->GetId(), winnerChange, loserChange);
if (sWorld->getBoolConfig(CONFIG_ARENA_LOG_EXTENDED_INFO))
for (Battleground::BattlegroundScoreMap::const_iterator itr = GetPlayerScoresBegin(); itr != GetPlayerScoresEnd(); ++itr)
if (Player* player = ObjectAccessor::FindPlayer(itr->first))
{
TC_LOG_DEBUG("bg.arena", "Statistics match Type: %u for %s (GUID: " UI64FMTD ", Team: %d, IP: %s): %u damage, %u healing, %u killing blows",
m_ArenaType, player->GetName().c_str(), itr->first, player->GetArenaTeamId(m_ArenaType == 5 ? 2 : m_ArenaType == 3),
SetArenaTeamRatingChangeForTeam(ALLIANCE, 0);
SetArenaTeamRatingChangeForTeam(HORDE, 0);
}
TC_LOG_INFO("arena.cheat", "Arena cheated, score is 0 for teams IDs %u and %u", winnerArenaTeam->GetId(),loserArenaTeam->GetId());
}
else
{
if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam)
{
if (winner != WINNER_NONE)
{
loserTeamRating = loserArenaTeam->GetRating();
loserMatchmakerRating = GetArenaMatchmakerRating(GetOtherTeam(winner));
winnerTeamRating = winnerArenaTeam->GetRating();
winnerMatchmakerRating = GetArenaMatchmakerRating(winner);
winnerMatchmakerChange = winnerArenaTeam->WonAgainst(winnerMatchmakerRating, loserMatchmakerRating, winnerChange);
loserMatchmakerChange = loserArenaTeam->LostAgainst(loserMatchmakerRating, winnerMatchmakerRating, loserChange);
TC_LOG_DEBUG("bg.arena", "match Type: %u --- Winner: old rating: %u, rating gain: %d, old MMR: %u, MMR gain: %d --- Loser: old rating: %u, rating loss: %d, old MMR: %u, MMR loss: %d ---", m_ArenaType, winnerTeamRating, winnerChange, winnerMatchmakerRating,
winnerMatchmakerChange, loserTeamRating, loserChange, loserMatchmakerRating, loserMatchmakerChange);
SetArenaMatchmakerRating(winner, winnerMatchmakerRating + winnerMatchmakerChange);
SetArenaMatchmakerRating(GetOtherTeam(winner), loserMatchmakerRating + loserMatchmakerChange);
SetArenaTeamRatingChangeForTeam(winner, winnerChange);
SetArenaTeamRatingChangeForTeam(GetOtherTeam(winner), loserChange);
TC_LOG_DEBUG("bg.arena", "Arena match Type: %u for Team1Id: %u - Team2Id: %u ended. WinnerTeamId: %u. Winner rating: +%d, Loser rating: %d", m_ArenaType, m_ArenaTeamIds[TEAM_ALLIANCE], m_ArenaTeamIds[TEAM_HORDE], winnerArenaTeam->GetId(), winnerChange, loserChange);
if (sWorld->getBoolConfig(CONFIG_ARENA_LOG_EXTENDED_INFO))
for (Battleground::BattlegroundScoreMap::const_iterator itr = GetPlayerScoresBegin(); itr != GetPlayerScoresEnd(); ++itr)
if (Player* player = ObjectAccessor::FindPlayer(itr->first))
{
TC_LOG_DEBUG("bg.arena", "Statistics match Type: %u for %s (GUID: " UI64FMTD ", Team: %d, IP: %s): %u damage, %u healing, %u killing blows",
m_ArenaType, player->GetName().c_str(), itr->first, player->GetArenaTeamId(m_ArenaType == 5 ? 2 : m_ArenaType == 3),
player->GetSession()->GetRemoteAddress().c_str(), itr->second->DamageDone, itr->second->HealingDone,
itr->second->KillingBlows);
}
}
}
// Deduct 16 points from each teams arena-rating if there are no winners after 45+2 minutes
else
{
SetArenaTeamRatingChangeForTeam(ALLIANCE, ARENA_TIMELIMIT_POINTS_LOSS);
SetArenaTeamRatingChangeForTeam(HORDE, ARENA_TIMELIMIT_POINTS_LOSS);
winnerArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS);
loserArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS);
}
}
// Deduct 16 points from each teams arena-rating if there are no winners after 45+2 minutes
else
{
SetArenaTeamRatingChangeForTeam(ALLIANCE, ARENA_TIMELIMIT_POINTS_LOSS);
SetArenaTeamRatingChangeForTeam(HORDE, ARENA_TIMELIMIT_POINTS_LOSS);
winnerArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS);
loserArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS);
SetArenaTeamRatingChangeForTeam(ALLIANCE, 0);
SetArenaTeamRatingChangeForTeam(HORDE, 0);
}
}
else
{
SetArenaTeamRatingChangeForTeam(ALLIANCE, 0);
SetArenaTeamRatingChangeForTeam(HORDE, 0);
}
}

WorldPacket pvpLogData;
Expand Down
1 change: 1 addition & 0 deletions src/server/game/Battlegrounds/Battleground.h
Expand Up @@ -465,6 +465,7 @@ class Battleground
void CheckArenaAfterTimerConditions();
void CheckArenaWinConditions();
void UpdateArenaWorldState();
bool CheckCheatArena(uint32 winTeam);

// Triggers handle
// must be implemented in BG subclass
Expand Down
8 changes: 8 additions & 0 deletions src/server/game/World/World.cpp
Expand Up @@ -1041,6 +1041,14 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_ARENA_START_MATCHMAKER_RATING] = sConfigMgr->GetIntDefault ("Arena.ArenaStartMatchmakerRating", 1500);
m_bool_configs[CONFIG_ARENA_SEASON_IN_PROGRESS] = sConfigMgr->GetBoolDefault("Arena.ArenaSeason.InProgress", true);
m_bool_configs[CONFIG_ARENA_LOG_EXTENDED_INFO] = sConfigMgr->GetBoolDefault("ArenaLog.ExtendedInfo", false);
m_bool_configs[CONFIG_ARENA_CHECK_CHEATERS] = sConfigMgr->GetBoolDefault("Arena.Cheated", false);
m_bool_configs[CONFIG_ARENA_CHECK_CHEATERS_ONLYLOG] = sConfigMgr->GetBoolDefault("Arena.Cheated.OnlyLOG", true);
m_float_configs[CONFIG_ARENA_CHECK_CHEATERS_2v2] = sConfigMgr->GetFloatDefault("Arena.Cheated.Rating.2v2", 0.5f);
m_float_configs[CONFIG_ARENA_CHECK_CHEATERS_3v3] = sConfigMgr->GetFloatDefault("Arena.Cheated.Rating.3v3", 0.66f);
m_float_configs[CONFIG_ARENA_CHECK_CHEATERS_5v5] = sConfigMgr->GetFloatDefault("Arena.Cheated.Rating.5v5", 0.75f);
m_int_configs[CONFIG_ARENA_CHECK_CHEATERS_MIN_DMG_2v2] = sConfigMgr->GetIntDefault ("Arena.Cheated.Minimum.Damage.2v2", 10);
m_int_configs[CONFIG_ARENA_CHECK_CHEATERS_MIN_DMG_3v3] = sConfigMgr->GetIntDefault ("Arena.Cheated.Minimum.Damage.2v2", 10);
m_int_configs[CONFIG_ARENA_CHECK_CHEATERS_MIN_DMG_5v5] = sConfigMgr->GetIntDefault ("Arena.Cheated.Minimum.Damage.2v2", 10);

m_bool_configs[CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN] = sConfigMgr->GetBoolDefault("OffhandCheckAtSpellUnlearn", true);

Expand Down
8 changes: 8 additions & 0 deletions src/server/game/World/World.h
Expand Up @@ -128,6 +128,8 @@ enum WorldBoolConfigs
CONFIG_ARENA_QUEUE_ANNOUNCER_PLAYERONLY,
CONFIG_ARENA_SEASON_IN_PROGRESS,
CONFIG_ARENA_LOG_EXTENDED_INFO,
CONFIG_ARENA_CHECK_CHEATERS,
CONFIG_ARENA_CHECK_CHEATERS_ONLYLOG,
CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN,
CONFIG_VMAP_INDOOR_CHECK,
CONFIG_START_ALL_SPELLS,
Expand Down Expand Up @@ -183,6 +185,9 @@ enum WorldFloatConfigs
CONFIG_STATS_LIMITS_PARRY,
CONFIG_STATS_LIMITS_BLOCK,
CONFIG_STATS_LIMITS_CRIT,
CONFIG_ARENA_CHECK_CHEATERS_2v2,
CONFIG_ARENA_CHECK_CHEATERS_3v3,
CONFIG_ARENA_CHECK_CHEATERS_5v5,
FLOAT_CONFIG_VALUE_COUNT
};

Expand Down Expand Up @@ -287,6 +292,9 @@ enum WorldIntConfigs
CONFIG_ARENA_START_RATING,
CONFIG_ARENA_START_PERSONAL_RATING,
CONFIG_ARENA_START_MATCHMAKER_RATING,
CONFIG_ARENA_CHECK_CHEATERS_MIN_DMG_2v2,
CONFIG_ARENA_CHECK_CHEATERS_MIN_DMG_3v3,
CONFIG_ARENA_CHECK_CHEATERS_MIN_DMG_5v5,
CONFIG_MAX_WHO,
CONFIG_HONOR_AFTER_DUEL,
CONFIG_PVP_TOKEN_MAP_TYPE,
Expand Down
38 changes: 38 additions & 0 deletions src/server/worldserver/worldserver.conf.dist
Expand Up @@ -2321,6 +2321,44 @@ Arena.ArenaStartMatchmakerRating = 1500

ArenaLog.ExtendedInfo = 0

#
# Arena.Cheated
# Description: Check if players are cheating in the arena.
# Default: 0 - (Disabled)
# 1 - (Enabled)
Arena.Cheated = 0

#
# Arena.Cheated.OnlyLOG
# Description: Check if should report only on Log file/console, allowing the system to award arena points.
# Default: 1 - (Enabled: Only reports if cheat detected)
# 0 - (Disabled: Reports and changes the award points to 0 if cheat detected)
Arena.Cheated.OnlyLOG = 1

#
# Arena.Cheated.Rating.2v2
# Arena.Cheated.Rating.3v3
# Arena.Cheated.Rating.5v5
# Description: Sets the threshold of minimum activity (heal+dmg) for the arenas
# Default: 2v2 - Default 50%
# 3v3 - Default 66%
# 5v5 - Default 75%
Arena.Cheated.Rating.2v2 = 0.5
Arena.Cheated.Rating.3v3 = 0.66
Arena.Cheated.Rating.5v5 = 0.75

#
# Arena.Cheated.Minimum.Damage.2v2
# Arena.Cheated.Minimum.Damage.3v3
# Arena.Cheated.Minimum.Damage.5v5
# Description: Sets minimum damage the Looser team (in %) on an Arena has to deal or it will be considered cheating
# Default: 2v2 - Default 10%
# 3v3 - Default 10%
# 5v5 - Default 10%
Arena.Cheated.Minimum.Damage.2v2 = 10
Arena.Cheated.Minimum.Damage.3v3 = 10
Arena.Cheated.Minimum.Damage.5v5 = 10

#
###################################################################################################

Expand Down

0 comments on commit 92c4b4e

Please sign in to comment.