CrossfactionBG - Última Revisão / Passive Anti-Hacker - Última Revisão

Bom amigos eu estou compartilhando alguns arquivos meus que atualizei alguns dias atrás:
Crossfaction BG
Anti Hacker para World Of Warcraft (Wotlk 3.3.5a) passivo ou seja não sei se irá bloquear o hacker mais irá te reportar quando um Administrador ou Game Master estiver online.

Basta aplicar os patchs abaixo, lembrando que esta atualizado com a última revisão da TrinityCore. Segue em anexo e abaixo o código caso deseja aplicar manualmente.

Crossfaction BG - Última Revisão - Código Abaixo:

From 4622d722c6dae54fd819b61b515d8d92ef87c50d Mon Sep 17 00:00:00 2001
From: Noffearr [email protected]
Date: Mon, 18 May 2015 10:49:46 -0400
Subject: [PATCH] * Patch CrossFaction

  • Atualizado e Fixado

src/server/game/Battlegrounds/Arena.cpp | 4 ±
src/server/game/Battlegrounds/Battleground.cpp | 55 +±-
src/server/game/Battlegrounds/Battleground.h | 2 ±
src/server/game/Battlegrounds/BattlegroundMgr.cpp | 2 ±
…/game/Battlegrounds/BattlegroundQueue.cpp | 83 ++±-
src/server/game/Battlegrounds/BattlegroundQueue.h | 11 ±
…/game/Battlegrounds/Zones/BattlegroundAB.cpp | 2 ±
…/game/Battlegrounds/Zones/BattlegroundAV.cpp | 19 ±
…/game/Battlegrounds/Zones/BattlegroundWS.cpp | 3 ±
src/server/game/CMakeLists.txt | 2 +
src/server/game/Cfbg/Cfbg.cpp | 347 +++++++++++++++++++++
src/server/game/Cfbg/Cfbg.h | 44 +++
src/server/game/Entities/Player/Player.cpp | 97 +++±-
src/server/game/Entities/Player/Player.h | 36 +±
src/server/game/Entities/Unit/Unit.cpp | 15 +
src/server/game/Entities/Unit/Unit.h | 4 ±
src/server/game/Handlers/BattleGroundHandler.cpp | 2 ±
src/server/game/Handlers/CharacterHandler.cpp | 3 +
src/server/game/Handlers/ChatHandler.cpp | 4 +
src/server/game/Handlers/MiscHandler.cpp | 15 +
src/server/game/Handlers/QueryHandler.cpp | 2 ±
src/server/game/World/World.cpp | 2 +
src/server/game/World/World.h | 1 +
src/server/worldserver/worldserver.conf.dist | 12 +
24 files changed, 666 insertions(+), 101 deletions(-)
create mode 100644 src/server/game/Cfbg/Cfbg.cpp
create mode 100644 src/server/game/Cfbg/Cfbg.h

diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp
index dc7f5b2…4defea7 100644
— a/src/server/game/Battlegrounds/Arena.cpp
+++ b/src/server/game/Battlegrounds/Arena.cpp
@@ -40,9 +40,9 @@ Arena::Arena()
void Arena::AddPlayer(Player* player)
{
Battleground::AddPlayer(player);

  • PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetBGTeam());
  • PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetTeam());
  • if (player->GetBGTeam() == ALLIANCE) // gold
  • if (player->GetTeam() == ALLIANCE) // gold
    {
    if (player->GetTeam() == HORDE)
    player->CastSpell(player, SPELL_HORDE_GOLD_FLAG, true);
    diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
    index e3ff372…6c67d2f 100644
    — a/src/server/game/Battlegrounds/Battleground.cpp
    +++ b/src/server/game/Battlegrounds/Battleground.cpp
    @@ -286,7 +286,7 @@ inline void Battleground::_CheckSafePositions(uint32 diff)
    if (Player* player = ObjectAccessor::FindPlayer(itr->first))
    {
    Position pos = player->GetPosition();
  •            Position const* startPos = GetTeamStartPosition(Battleground::GetTeamIndexByTeamId(player->GetBGTeam()));
    
  •            Position const* startPos = GetTeamStartPosition(Battleground::GetTeamIndexByTeamId(player->GetTeam()));
               if (pos.GetExactDistSq(startPos) > maxDist)
               {
                   TC_LOG_DEBUG("bg.battleground", "BATTLEGROUND: Sending %s back to start location (map: %u) (possible exploit)", player->GetName().c_str(), GetMapId());
    

@@ -502,7 +502,7 @@ inline void Battleground::_ProcessJoin(uint32 diff)
WorldPacket status;
BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(m_TypeID, GetArenaType());
uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId);

  •                sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), player->GetBGTeam());
    
  •                sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), player->GetTeam());
                   player->SendDirectMessage(&status);
    
                   player->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
    

@@ -672,23 +672,34 @@ void Battleground::RewardHonorToTeam(uint32 Honor, uint32 TeamID)
UpdatePlayerScore(player, SCORE_BONUS_HONOR, Honor);
}

-void Battleground::RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID)
+void Battleground::RewardReputationToTeam(uint32 a_faction_id, uint32 h_faction_id, uint32 Reputation, uint32 TeamID)
{

  • FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id);
  • if (!factionEntry)
  •    return;
    
  • FactionEntry const* a_factionEntry = sFactionStore.LookupEntry(a_faction_id);
  • FactionEntry const* h_factionEntry = sFactionStore.LookupEntry(h_faction_id);
  • for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
  • {
  •    Player* player = _GetPlayerForTeam(TeamID, itr, "RewardReputationToTeam");
    
  •    if (!player)
    
  •        continue;
    
  • if (!a_factionEntry || !h_factionEntry)
  •   return;
    
  •    uint32 repGain = Reputation;
    
  •    AddPct(repGain, player->GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN));
    
  •    AddPct(repGain, player->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_FACTION_REPUTATION_GAIN, faction_id));
    
  •    player->GetReputationMgr().ModifyReputation(factionEntry, repGain);
    
  • }
  • for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
  • {
  •   if (itr->second.OfflineRemoveTime)
    
  •   	continue;
    
  •   Player* player = ObjectAccessor::FindPlayer(itr->first);
    
  •   if (!player)
    
  •   {
    
  •   	TC_LOG_ERROR("bg.battleground", "BattleGround:RewardReputationToTeam: %u not found!", itr->first);
    
  •   	continue;
    
  •   }
    
  •   uint32 team = player->GetTeam();
    
  •   if (team == TeamID)
    
  •   if (Player* player = _GetPlayerForTeam(TeamID, itr, "RewardReputationToTeam"))
    
  •   {
    
  •   	player->GetReputationMgr().ModifyReputation(player->GetCFSTeam() == ALLIANCE ? a_factionEntry : h_factionEntry, Reputation);
    
  •   }
    
  • }
    }

void Battleground::UpdateWorldState(uint32 Field, uint32 Value)
@@ -840,7 +851,7 @@ void Battleground::EndBattleground(uint32 winner)
player->SendDirectMessage(&pvpLogData);

     WorldPacket data;
  •    sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), player->GetBGTeam());
    
  •    sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), player->GetTeam());
       player->SendDirectMessage(&data);
       player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1);
    

    }
    @@ -956,6 +967,7 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen

    if (player)
    {

  •   player->FitPlayerInTeam(false, this);
       // Do next only if found in battleground
       player->SetBattlegroundId(0, BATTLEGROUND_TYPE_NONE);  // We're not in BG.
       // reset destination bg team
    

@@ -1024,7 +1036,7 @@ void Battleground::AddPlayer(Player* player)

 // score struct must be created in inherited class
  • uint32 team = player->GetBGTeam();
  • uint32 team = player->GetTeam();

    BattlegroundPlayer bp;
    bp.OfflineRemoveTime = 0;
    @@ -1075,6 +1087,7 @@ void Battleground::AddPlayer(Player* player)
    // setup BG group membership
    PlayerAddedToBGCheckIfBGIsRunning(player);
    AddOrSetPlayerToCorrectBgGroup(player, team);

  • player->FitPlayerInTeam(true, this);
    }

// this method adds player to his team’s bg group, or sets his correct group if player is already in bg group
@@ -1144,8 +1157,8 @@ void Battleground::EventPlayerLoggedOut(Player* player)

     // 1 player is logging out, if it is the last, then end arena!
     if (isArena())
  •        if (GetAlivePlayersCountByTeam(player->GetBGTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetBGTeam())))
    
  •            EndBattleground(GetOtherTeam(player->GetBGTeam()));
    
  •   	if (GetAlivePlayersCountByTeam(player->GetTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetTeam())))
    
  •   		EndBattleground(GetOtherTeam(player->GetTeam()));
    
    }
    }

@@ -1758,7 +1771,7 @@ void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player)
BuildPvPLogDataPacket(data);
player->SendDirectMessage(&data);

  • sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), player->GetBGTeam());
  • sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), player->GetTeam());
    player->SendDirectMessage(&data);
    }

diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index 19414e6…715ae82 100644
— a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -355,7 +355,7 @@ class Battleground
void CastSpellOnTeam(uint32 SpellID, uint32 TeamID);
void RemoveAuraOnTeam(uint32 SpellID, uint32 TeamID);
void RewardHonorToTeam(uint32 Honor, uint32 TeamID);

  •    void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID);
    
  •   void RewardReputationToTeam(uint32 a_faction_id, uint32 h_faction_id, uint32 Reputation, uint32 TeamID);
       void UpdateWorldState(uint32 Field, uint32 Value);
       void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player* player);
       virtual void EndBattleground(uint32 winner);
    

diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
index 3a95f58…faa72e3 100644
— a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
@@ -693,7 +693,7 @@ void BattlegroundMgr::SendToBattleground(Player* player, uint32 instanceId, Batt
if (Battleground* bg = GetBattleground(instanceId, bgTypeId))
{
uint32 mapid = bg->GetMapId();

  •    uint32 team = player->GetBGTeam();
    
  •    uint32 team = player->GetTeam();
       if (team == 0)
           team = player->GetTeam();
    

diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
index 1006b5e…06bbf63 100644
— a/src/server/game/Battlegrounds/BattlegroundQueue.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
@@ -154,6 +154,10 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr
index += BG_TEAMS_COUNT;
if (ginfo->Team == HORDE)
index++;
+

  • if (sWorld->getBoolConfig(CROSSFACTION_SYSTEM_BATTLEGROUNDS) && ArenaType == 0)

  •   index = BG_QUEUE_CROSSFACTION;
    
  • TC_LOG_DEBUG(“bg.battleground”, “Adding Group to BattlegroundQueue bgTypeId : %u, bracket_id : %u, index : %u”, BgTypeId, bracketId, index);

    uint32 lastOnlineTime = getMSTime();
    @@ -198,30 +202,57 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr
    {
    if (Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(ginfo->BgTypeId))
    {

  •            uint32 MinPlayers = bg->GetMinPlayersPerTeam();
    
  •            uint32 qHorde = 0;
    
  •            uint32 qAlliance = 0;
    
  •            uint32 q_min_level = bracketEntry->minLevel;
    
  •            uint32 q_max_level = bracketEntry->maxLevel;
    
  •            GroupsQueueType::const_iterator itr;
    
  •            for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr)
    
  •                if (!(*itr)->IsInvitedToBGInstanceGUID)
    
  •                    qAlliance += (*itr)->Players.size();
    
  •            for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].end(); ++itr)
    
  •                if (!(*itr)->IsInvitedToBGInstanceGUID)
    
  •                    qHorde += (*itr)->Players.size();
    
  •            // Show queue status to player only (when joining queue)
    
  •            if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
    
  •   		if (sWorld->getBoolConfig(CROSSFACTION_SYSTEM_BATTLEGROUNDS))
               {
    
  •                ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bg->GetName().c_str(), q_min_level, q_max_level,
    
  •                    qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
    
  •   			char const* bgName = bg->GetName().c_str();
    
  •   			uint32 MinPlayers = bg->GetMinPlayersPerTeam() * 2;
    
  •   			uint32 qPlayers = 0;
    
  •   			uint32 q_min_level = bracketEntry->minLevel;
    
  •   			uint32 q_max_level = bracketEntry->maxLevel;
    
  •   			for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracketId][BG_QUEUE_CROSSFACTION].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_CROSSFACTION].end(); ++itr)
    
  •   			if (!(*itr)->IsInvitedToBGInstanceGUID)
    
  •   				qPlayers += (*itr)->Players.size();
    
  •   			if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
    
  •   			{
    
  •   				ChatHandler(leader->GetSession()).PSendSysMessage("Queue status for %s (Lvl: %u to %u) Queued players: %u (Need at least %u more)", bgName, q_min_level, q_max_level, qPlayers, MinPlayers - qPlayers);
    
  •   			}
    
  •   			else
    
  •   			{
    
  •   				std::ostringstream ss;
    
  •   				ss << "|cffff0000[BG Queue Announcer]:|r " << bgName << " -- [" << q_min_level << "-" << q_max_level << "] " << qPlayers << "/" << MinPlayers;
    
  •   				sWorld->SendGlobalText(ss.str().c_str(), NULL);
    
  •   			}
               }
    
  •            // System message
               else
               {
    
  •                sWorld->SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bg->GetName().c_str(), q_min_level, q_max_level,
    
  •                    qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
    
  •   			//	std::string bgName = bg->GetName().c_str();
    
  •   			char const* bgName = bg->GetName().c_str();
    
  •   			uint32 MinPlayers = bg->GetMinPlayersPerTeam();
    
  •   			uint32 qHorde = 0;
    
  •   			uint32 qAlliance = 0;
    
  •   			uint32 q_min_level = bracketEntry->minLevel;
    
  •   			uint32 q_max_level = bracketEntry->maxLevel;
    
  •   			GroupsQueueType::const_iterator itr;
    
  •   			for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr)
    
  •   			if (!(*itr)->IsInvitedToBGInstanceGUID)
    
  •   				qAlliance += (*itr)->Players.size();
    
  •   			for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].end(); ++itr)
    
  •   			if (!(*itr)->IsInvitedToBGInstanceGUID)
    
  •   				qHorde += (*itr)->Players.size();
    
  •   			// Show queue status to player only (when joining queue)
    
  •   			if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
    
  •   			{
    
  •   				ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bgName, q_min_level, q_max_level, //******
    
  •   					qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
    
  •   			}
    
  •   			// System message
    
  •   			else
    
  •   			{
    
  •   				sWorld->SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bgName, q_min_level, q_max_level, //*******
    
  •   					qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
    
  •   			}
               }
           }
       }
    

@@ -308,7 +339,7 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
{
//we must check premade and normal team’s queue - because when players from premade are joining bg,
//they leave groupinfo so we can’t use its players size to find out index

  •    for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += BG_TEAMS_COUNT)
    
  •   for (uint8 j = 0; j < BG_QUEUE_GROUP_TYPES_COUNT; ++j)
       {
           GroupsQueueType::iterator k = m_QueuedGroups[bracket_id_tmp][j].begin();
           for (; k != m_QueuedGroups[bracket_id_tmp][j].end(); ++k)
    

@@ -497,6 +528,10 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId
int32 hordeFree = bg->GetFreeSlotsForTeam(HORDE);
int32 aliFree = bg->GetFreeSlotsForTeam(ALLIANCE);

  • if (!bg->isArena())
  • if (FillXPlayersToBG(bracket_id, bg, false))
  •   return;
    
  • //iterator for iterating through bg queue
    GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].begin();
    //count of groups in queue - used to stop cycles
    @@ -745,7 +780,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /diff/, BattlegroundTyp
    if (m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty() &&
    m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty() &&
    m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].empty() &&
  •    m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].empty())
    
  •   m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].empty() &&
    
  •   m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].empty())
       return;
    

    // battleground with free slot for player should be always in the beggining of the queue
    @@ -836,7 +872,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /diff/, BattlegroundTyp
    {
    // if there are enough players in pools, start new battleground or non rated arena
    if (CheckNormalMatch(bg_template, bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam)

  •        || (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam)))
    
  •   	|| (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam))
    
  •   	|| CheckCrossFactionMatch(bracket_id, bg_template))
       {
           // we successfully created a pool
           Battleground* bg2 = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, arenaType, false);
    

diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.h b/src/server/game/Battlegrounds/BattlegroundQueue.h
index b3b7fb3…466678f 100644
— a/src/server/game/Battlegrounds/BattlegroundQueue.h
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.h
@@ -42,6 +42,7 @@ struct GroupQueueInfo // stores informatio
{
std::map<ObjectGuid, PlayerQueueInfo*> Players; // player queue info map
uint32 Team; // Player team (ALLIANCE/HORDE)

  • uint32 CFSTeam; // Player team (ALLIANCE/HORDE)
    BattlegroundTypeId BgTypeId; // battleground type id
    bool IsRated; // rated
    uint8 ArenaType; // 2v2, 3v3, 5v5 or 0 when BG
    @@ -60,9 +61,10 @@ enum BattlegroundQueueGroupTypes
    BG_QUEUE_PREMADE_ALLIANCE = 0,
    BG_QUEUE_PREMADE_HORDE = 1,
    BG_QUEUE_NORMAL_ALLIANCE = 2,
  • BG_QUEUE_NORMAL_HORDE = 3
  • BG_QUEUE_NORMAL_HORDE = 3,
  • BG_QUEUE_CROSSFACTION = 4
    };
    -#define BG_QUEUE_GROUP_TYPES_COUNT 4
    +#define BG_QUEUE_GROUP_TYPES_COUNT 5

class Battleground;
class BattlegroundQueue
@@ -74,6 +76,11 @@ class BattlegroundQueue
void BattlegroundQueueUpdate(uint32 diff, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0);
void UpdateEvents(uint32 diff);

  •   bool FillXPlayersToBG(BattlegroundBracketId bracket_id, Battleground* bg, bool start = false);
    
  •   typedef std::multimap<int32, GroupQueueInfo*> QueuedGroupMap;
    
  •   int32 PreAddPlayers(QueuedGroupMap m_PreGroupMap, int32 MaxAdd, uint32 MaxInTeam);
    
  •   bool CheckCrossFactionMatch(BattlegroundBracketId bracket_id, Battleground* bg);
    
  •    void FillPlayersToBG(Battleground* bg, BattlegroundBracketId bracket_id);
       bool CheckPremadeMatch(BattlegroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam);
       bool CheckNormalMatch(Battleground* bg_template, BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers);
    

diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
index 01acd78…d5560dc 100644
— a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
@@ -139,7 +139,7 @@ void BattlegroundAB::PostUpdateImpl(uint32 diff)

             if (m_ReputationScoreTics[team] >= m_ReputationTics)
             {
  •                (team == TEAM_ALLIANCE) ? RewardReputationToTeam(509, 10, ALLIANCE) : RewardReputationToTeam(510, 10, HORDE);
    
  •   			RewardReputationToTeam(509, 510, 10, team == ALLIANCE ? ALLIANCE : HORDE);
                   m_ReputationScoreTics[team] -= m_ReputationTics;
               }
    

diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
index 016a113…060097e 100644
— a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
@@ -88,7 +88,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer)
if (entry == BG_AV_CreatureInfo[AV_NPC_A_BOSS])
{
CastSpellOnTeam(23658, HORDE); //this is a spell which finishes a quest where a player has to kill the boss

  •    RewardReputationToTeam(729, BG_AV_REP_BOSS, HORDE);
    
  •   RewardReputationToTeam(729, 730, BG_AV_REP_BOSS, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE);
       RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_BOSS), HORDE);
       EndBattleground(HORDE);
       DelCreature(AV_CPLACE_TRIGGER17);
    

@@ -96,7 +96,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer)
else if (entry == BG_AV_CreatureInfo[AV_NPC_H_BOSS])
{
CastSpellOnTeam(23658, ALLIANCE); //this is a spell which finishes a quest where a player has to kill the boss

  •    RewardReputationToTeam(730, BG_AV_REP_BOSS, ALLIANCE);
    
  •   RewardReputationToTeam(729, 730, BG_AV_REP_BOSS, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE);
       RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_BOSS), ALLIANCE);
       EndBattleground(ALLIANCE);
       DelCreature(AV_CPLACE_TRIGGER19);
    

@@ -109,7 +109,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer)
return;
}
m_CaptainAlive[0]=false;

  •    RewardReputationToTeam(729, BG_AV_REP_CAPTAIN, HORDE);
    
  •   RewardReputationToTeam(729, 730, BG_AV_REP_CAPTAIN, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE);
       RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), HORDE);
       UpdateScore(ALLIANCE, (-1)*BG_AV_RES_CAPTAIN);
       //spawn destroyed aura
    

@@ -128,7 +128,7 @@ void BattlegroundAV::HandleKillUnit(Creature* unit, Player* killer)
return;
}
m_CaptainAlive[1]=false;

  •    RewardReputationToTeam(730, BG_AV_REP_CAPTAIN, ALLIANCE);
    
  •   RewardReputationToTeam(729, 730, BG_AV_REP_CAPTAIN, killer->GetTeam() == ALLIANCE ? ALLIANCE : HORDE);
       RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), ALLIANCE);
       UpdateScore(HORDE, (-1)*BG_AV_RES_CAPTAIN);
       //spawn destroyed aura
    

@@ -150,6 +150,7 @@ void BattlegroundAV::HandleQuestComplete(uint32 questid, Player* player)
if (GetStatus() != STATUS_IN_PROGRESS)
return;//maybe we should log this, cause this must be a cheater or a big bug
uint8 team = GetTeamIndexByTeamId(player->GetTeam());

  • uint8 CFSteam = GetTeamIndexByTeamId(GetOtherTeam(player->GetTeam()));
    /// @todo add reputation, events (including quest not available anymore, next quest available, go/npc de/spawning)and maybe honor
    TC_LOG_DEBUG(“bg.battleground”, “BG_AV Quest %i completed”, questid);
    switch (questid)
    @@ -174,21 +175,21 @@ void BattlegroundAV::HandleQuestComplete(uint32 questid, Player* player)
    case AV_QUEST_A_COMMANDER1:
    case AV_QUEST_H_COMMANDER1:
    m_Team_QuestStatus[team][1]++;
  •        RewardReputationToTeam(team, 1, player->GetTeam());
    
  •   	RewardReputationToTeam(team, CFSteam, 1, player->GetTeam());
           if (m_Team_QuestStatus[team][1] == 30)
               TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed (need to implement some events here", questid);
           break;
       case AV_QUEST_A_COMMANDER2:
       case AV_QUEST_H_COMMANDER2:
           m_Team_QuestStatus[team][2]++;
    
  •        RewardReputationToTeam(team, 1, player->GetTeam());
    
  •   	RewardReputationToTeam(team, CFSteam, 1, player->GetTeam());
           if (m_Team_QuestStatus[team][2] == 60)
               TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed (need to implement some events here", questid);
           break;
       case AV_QUEST_A_COMMANDER3:
       case AV_QUEST_H_COMMANDER3:
           m_Team_QuestStatus[team][3]++;
    
  •        RewardReputationToTeam(team, 1, player->GetTeam());
    
  •   	RewardReputationToTeam(team, CFSteam, 1, player->GetTeam());
           if (m_Team_QuestStatus[team][3] == 120)
               TC_LOG_DEBUG("bg.battleground", "BG_AV Quest %i completed (need to implement some events here", questid);
           break;
    

@@ -470,7 +471,7 @@ void BattlegroundAV::EndBattleground(uint32 winner)
rep[i] += BG_AV_REP_SURVIVING_CAPTAIN;
}
if (rep[i] != 0)

  •        RewardReputationToTeam(i == 0 ? 730 : 729, rep[i], i == 0 ? ALLIANCE : HORDE);
    
  •   	RewardReputationToTeam(729, 730, 10, i == ALLIANCE ? ALLIANCE : HORDE);
       if (kills[i] != 0)
           RewardHonorToTeam(GetBonusHonorFromKill(kills[i]), i == 0 ? ALLIANCE : HORDE);
    

    }
    @@ -575,7 +576,7 @@ void BattlegroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node)
    SpawnBGObject(BG_AV_OBJECT_BURN_DUNBALDAR_SOUTH + i + (tmp * 10), RESPAWN_IMMEDIATELY);

       UpdateScore((owner == ALLIANCE) ? HORDE : ALLIANCE, -1 * BG_AV_RES_TOWER);
    
  •    RewardReputationToTeam(owner == ALLIANCE ? 730 : 729, BG_AV_REP_TOWER, owner);
    
  •   RewardReputationToTeam(729, 730, BG_AV_REP_TOWER, owner);
       RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_TOWER), owner);
    
       SpawnBGObject(BG_AV_OBJECT_TAURA_A_DUNBALDAR_SOUTH+GetTeamIndexByTeamId(owner)+(2*tmp), RESPAWN_ONE_DAY);
    

diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
index ef02b24…7a0f325 100644
— a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
@@ -307,7 +307,6 @@ void BattlegroundWS::EventPlayerCapturedFlag(Player* player)
if (GetTeamScore(TEAM_ALLIANCE) < BG_WS_MAX_TEAM_SCORE)
AddPoint(ALLIANCE, 1);
PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE);

  •    RewardReputationToTeam(890, m_ReputationCapture, ALLIANCE);
    
    }
    else
    {
    @@ -326,8 +325,8 @@ void BattlegroundWS::EventPlayerCapturedFlag(Player* player)
    if (GetTeamScore(TEAM_HORDE) < BG_WS_MAX_TEAM_SCORE)
    AddPoint(HORDE, 1);
    PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE);
  •    RewardReputationToTeam(889, m_ReputationCapture, HORDE);
    
    }
  • RewardReputationToTeam(890, 889, m_ReputationCapture, player->GetTeam());
    //for flag capture is reward 2 honorable kills
    RewardHonorToTeam(GetBonusHonorFromKill(2), player->GetTeam());

diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
index b604209…ff39e7f 100644
— a/src/server/game/CMakeLists.txt
+++ b/src/server/game/CMakeLists.txt
@@ -50,6 +50,7 @@ file(GLOB_RECURSE sources_Tickets Tickets/.cpp Tickets/.h)
file(GLOB_RECURSE sources_Warden Warden/.cpp Warden/.h)
file(GLOB_RECURSE sources_Weather Weather/.cpp Weather/.h)
file(GLOB_RECURSE sources_World World/.cpp World/.h)
+file(GLOB_RECURSE sources_Cfbg Cfbg/.cpp Cfbg/.h)

Create game-libary

@@ -102,6 +103,7 @@ set(game_STAT_SRCS
${sources_Warden}
${sources_Weather}
${sources_World}

  • ${sources_Cfbg}
    )

include_directories(
diff --git a/src/server/game/Cfbg/Cfbg.cpp b/src/server/game/Cfbg/Cfbg.cpp
new file mode 100644
index 0000000…b02db1c
— /dev/null
+++ b/src/server/game/Cfbg/Cfbg.cpp
@@ -0,0 +1,347 @@
+/*

    • This program is free software; you can redistribute it and/or modify it
    • under the terms of the GNU General Public License as published by the
    • Free Software Foundation; either version 2 of the License, or (at your
    • option) any later version.
    • This program is distributed in the hope that it will be useful, but WITHOUT
    • ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    • FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
    • more details.
    • You should have received a copy of the GNU General Public License along

+#include “Cfbg.h”
+#include “Battleground.h”
+#include “BattlegroundMgr.h”
+#include “Player.h”
+#include “Chat.h”
+#include “BattlegroundQueue.h”
+
+/####################################################################################
+###############################CROSSFACTION BATTLEGROUNDS#############################
+####################################################################################
/
+
+uint8 Unit::getRace(bool forceoriginal) const
+{

  • if (GetTypeId() == TYPEID_PLAYER)
  • {
  •   Player* pPlayer = ((Player*)this);
    
  •   if (forceoriginal)
    
  •   	return pPlayer->getCFSRace();
    
  •   if (pPlayer->InArena())
    
  •   	return GetByteValue(UNIT_FIELD_BYTES_0, 0);
    
  •   if (!pPlayer->IsPlayingNative())
    
  •   	return pPlayer->getFRace();
    
  • }
  • return GetByteValue(UNIT_FIELD_BYTES_0, 0);
    +}

+bool Player::SendRealNameQuery()
+{

  • if (IsPlayingNative())
  •   return false;
    
  • WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8 + 1 + 1 + 1 + 1 + 1 + 10));
  • data.appendPackGUID(GetGUID()); // player guid
  • data << uint8(0); // added in 3.1; if > 1, then end of packet
  • data << GetName(); // played name
  • data << uint8(0); // realm name for cross realm BG usage
  • data << uint8(getCFSRace());
  • data << uint8(getGender());
  • data << uint8(getClass());
  • data << uint8(0); // is not declined
  • GetSession()->SendPacket(&data);
  • return true;
    +}

+void Player::SetFakeRaceAndMorph()
+{

  • if (getClass() == CLASS_DRUID)
  • {
  •   if (GetCFSTeam() == ALLIANCE)
    
  •   {
    
  •   	m_FakeMorph = getGender() == GENDER_MALE ? FAKE_M_TAUREN : FAKE_F_TAUREN;
    
  •   	m_FakeRace = RACE_TAUREN;
    
  •   }
    
  •   else if (getGender() == GENDER_MALE) // HORDE PLAYER, ONLY HAVE MALE NELF ID
    
  •   {
    
  •   	m_FakeMorph = FAKE_M_NELF;
    
  •   	m_FakeRace = RACE_NIGHTELF;
    
  •   }
    
  •   else
    
  •   	m_FakeRace = GetCFSTeam() == ALLIANCE ? RACE_BLOODELF : RACE_HUMAN;
    
  • }
  • else if (getClass() == CLASS_SHAMAN && GetCFSTeam() == HORDE && getGender() == GENDER_FEMALE)
  • {
  •   m_FakeMorph = FAKE_F_DRAENEI; // Female Draenei
    
  •   m_FakeRace = RACE_DRAENEI;
    
  • }
  • else
  • {
  •   m_FakeRace = GetCFSTeam() == ALLIANCE ? RACE_BLOODELF : RACE_HUMAN;
    
  •   if (GetCFSTeam() == HORDE)
    
  •   {
    
  •   	if (getGender() == GENDER_MALE)
    
  •   		m_FakeMorph = 19723;
    
  •   	else
    
  •   		m_FakeMorph = 19724;
    
  •   }
    
  •   else
    
  •   {
    
  •   	if (getGender() == GENDER_MALE)
    
  •   		m_FakeMorph = 20578;
    
  •   	else
    
  •   		m_FakeMorph = 20579;
    
  •   }
    
  • }
    +}

+bool Player::SendBattleGroundChat(uint32 msgtype, std::string message)
+{

  • // Select distance to broadcast to.
  • float distance = msgtype == CHAT_MSG_SAY ? sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY) : sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL);
  • if (Battleground* pBattleGround = GetBattleground())
  • {
  •   if (pBattleGround->isArena()) // Only fake chat in BG's. CFBG should not interfere with arenas.
    
  •   	return false;
    
  •   for (Battleground::BattlegroundPlayerMap::const_iterator itr = pBattleGround->GetPlayers().begin(); itr != pBattleGround->GetPlayers().end(); ++itr)
    
  •   {
    
  •   	if (Player* pPlayer = ObjectAccessor::FindPlayer(itr->first))
    
  •   	{
    
  •   		if (GetDistance2d(pPlayer->GetPositionX(), pPlayer->GetPositionY()) <= distance)
    
  •   		{
    
  •   			WorldPacket data(SMSG_MESSAGECHAT, 200);
    
  •   			if (GetTeam() == pPlayer->GetTeam())
    
  •   			{
    
  •   				WorldPacket data;
    
  •   				ChatHandler::BuildChatPacket(data, ChatMsg(msgtype), LANG_UNIVERSAL, pPlayer, NULL, message);
    
  •   				pPlayer->GetSession()->SendPacket(&data);
    
  •   			}
    
  •   			else if (msgtype != CHAT_MSG_EMOTE)
    
  •   			{
    
  •   				WorldPacket data;
    
  •   				ChatHandler::BuildChatPacket(data, ChatMsg(msgtype), pPlayer->GetTeam() == ALLIANCE ? LANG_ORCISH : LANG_COMMON, pPlayer, NULL, message);
    
  •   				pPlayer->GetSession()->SendPacket(&data);
    
  •   			}
    
  •   			pPlayer->GetSession()->SendPacket(&data);
    
  •   		}
    
  •   	}
    
  •   }
    
  •   return true;
    
  • }
  • else
  •   return false;
    

+}
+
+void Player::MorphFit(bool value)
+{

  • if (!IsPlayingNative() && value)
  • {
  •   SetDisplayId(GetFakeMorph());
    
  •   SetNativeDisplayId(GetFakeMorph());
    
  • }
  • else
  •   InitDisplayIds();
    

+}
+
+void Player::FitPlayerInTeam(bool action, Battleground* pBattleGround)
+{

  • if (!pBattleGround)
  •   pBattleGround = GetBattleground();
    
  • if ((!pBattleGround || pBattleGround->isArena()) && action)
  •   return;
    
  • if (!IsPlayingNative() && action)
  •   setFactionForRace(getRace());
    
  • else
  •   setFactionForRace(getCFSRace());
    
  • if (action)
  •   SetForgetBGPlayers(true);
    
  • else
  •   SetForgetInListPlayers(true);
    
  • MorphFit(action);
  • if (pBattleGround && action)
  •   SendChatMessage("%sYou are playing for the %s%s in this %s", MSG_COLOR_WHITE, GetTeam() == ALLIANCE ? MSG_COLOR_DARKBLUE"alliance" : MSG_COLOR_RED"horde", MSG_COLOR_WHITE, pBattleGround->GetName().c_str());
    

+}
+
+void Player::DoForgetPlayersInList()
+{

  • // m_FakePlayers is filled from a vector within the battleground
  • // they were in previously so all players that have been in that BG will be invalidated.
  • for (FakePlayers::const_iterator itr = m_FakePlayers.begin(); itr != m_FakePlayers.end(); ++itr)
  • {
  •   WorldPacket data(SMSG_INVALIDATE_PLAYER, 8);
    
  •   data << *itr;
    
  •   GetSession()->SendPacket(&data);
    
  •   if (Player* pPlayer = ObjectAccessor::FindPlayer(ObjectGuid(*itr)))
    
  • // if (Player* pPlayer = ObjectAccessor::FindPlayer(*itr))
  •   	GetSession()->SendNameQueryOpcode(pPlayer->GetGUID());
    
  • }
  • m_FakePlayers.clear();
    +}

+void Player::DoForgetPlayersInBG(Battleground* pBattleGround)
+{

  • for (Battleground::BattlegroundPlayerMap::const_iterator itr = pBattleGround->GetPlayers().begin(); itr != pBattleGround->GetPlayers().end(); ++itr)
  • {
  •   // Here we invalidate players in the bg to the added player
    
  •   WorldPacket data1(SMSG_INVALIDATE_PLAYER, 8);
    
  •   data1 << itr->first;
    
  •   GetSession()->SendPacket(&data1);
    
  •   if (Player* pPlayer = ObjectAccessor::FindPlayer(itr->first))
    
  •   {
    
  •   	GetSession()->SendNameQueryOpcode(pPlayer->GetGUID()); // Send namequery answer instantly if player is available
    
  •   	// Here we invalidate the player added to players in the bg
    
  •   	WorldPacket data2(SMSG_INVALIDATE_PLAYER, 8);
    
  •   	data2 << GetGUID();
    
  •   	pPlayer->GetSession()->SendPacket(&data2);
    
  •   	pPlayer->GetSession()->SendNameQueryOpcode(GetGUID());
    
  •   }
    
  • }
    +}

+bool BattlegroundQueue::CheckCrossFactionMatch(BattlegroundBracketId bracket_id, Battleground* bg)
+{

  • if (!sWorld->getBoolConfig(CROSSFACTION_SYSTEM_BATTLEGROUNDS) || bg->isArena())
  •   return false; // Only do this if crossbg's are enabled.
    
  • // Here we will add all players to selectionpool, later we check if there are enough and launch a bg.
  • FillXPlayersToBG(bracket_id, bg, true);
  • if (sBattlegroundMgr->isTesting() && (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[TEAM_HORDE].GetPlayerCount()))
  •   return true;
    
  • uint8 MPT = bg->GetMinPlayersPerTeam();
  • if (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() < MPT || m_SelectionPools[TEAM_HORDE].GetPlayerCount() < MPT)
  •   return false;
    
  • return true;
    +}

+// This function will invite players in the least populated faction, which makes battleground queues much faster.
+// This function will return true if cross faction battlegrounds are enabled, otherwise return false,
+// which is useful in FillPlayersToBG. Because then we can interrupt the regular invitation if cross faction bg’s are enabled.
+bool BattlegroundQueue::FillXPlayersToBG(BattlegroundBracketId bracket_id, Battleground* bg, bool start)
+{

  • uint8 queuedPeople = 0;
  • for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].end(); ++itr)
  •   if (!(*itr)->IsInvitedToBGInstanceGUID)
    
  •   	queuedPeople += (*itr)->Players.size();
    
  •   if (sWorld->getBoolConfig(CROSSFACTION_SYSTEM_BATTLEGROUNDS) && (sBattlegroundMgr->isTesting() || queuedPeople >= bg->GetMinPlayersPerTeam() * 2 || !start))
    
  • {
  •   int32 aliFree = start ? bg->GetMaxPlayersPerTeam() : bg->GetFreeSlotsForTeam(ALLIANCE);
    
  •   int32 hordeFree = start ? bg->GetMaxPlayersPerTeam() : bg->GetFreeSlotsForTeam(HORDE);
    
  •   // Empty selection pools. They will be refilled from queued groups.
    
  •   m_SelectionPools[TEAM_ALLIANCE].Init();
    
  •   m_SelectionPools[TEAM_HORDE].Init();
    
  •   int32 valiFree = aliFree;
    
  •   int32 vhordeFree = hordeFree;
    
  •   int32 diff = 0;
    
  •   // Add teams to their own factions as far as possible.
    
  •   if (start)
    
  •   {
    
  •   	QueuedGroupMap m_PreGroupMap_a, m_PreGroupMap_h;
    
  •   	int32 m_SmallestOfTeams = 0;
    
  •   	int32 queuedAlliance = 0;
    
  •   	int32 queuedHorde = 0;
    
  •   	for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].end(); ++itr)
    
  •   	{
    
  •   		if ((*itr)->IsInvitedToBGInstanceGUID)
    
  •   			continue;
    
  •   		bool alliance = (*itr)->CFSTeam == ALLIANCE;
    
  •   		if (alliance)
    
  •   		{
    
  •   			m_PreGroupMap_a.insert(std::make_pair((*itr)->Players.size(), *itr));
    
  •   			queuedAlliance += (*itr)->Players.size();
    
  •   		}
    
  •   		else
    
  •   		{
    
  •   			m_PreGroupMap_h.insert(std::make_pair((*itr)->Players.size(), *itr));
    
  •   			queuedHorde += (*itr)->Players.size();
    
  •   		}
    
  •   	}
    
  •   	m_SmallestOfTeams = std::min(std::min(aliFree, queuedAlliance), std::min(hordeFree, queuedHorde));
    
  •   	valiFree -= PreAddPlayers(m_PreGroupMap_a, m_SmallestOfTeams, aliFree);
    
  •   	vhordeFree -= PreAddPlayers(m_PreGroupMap_h, m_SmallestOfTeams, hordeFree);
    
  •   }
    
  •   QueuedGroupMap m_QueuedGroupMap;
    
  •   for (GroupsQueueType::const_iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_CROSSFACTION].end(); ++itr)
    
  •   	m_QueuedGroupMap.insert(std::make_pair((*itr)->Players.size(), *itr));
    
  •   for (QueuedGroupMap::reverse_iterator itr = m_QueuedGroupMap.rbegin(); itr != m_QueuedGroupMap.rend(); ++itr)
    
  •   {
    
  •   	GroupsQueueType allypool = m_SelectionPools[TEAM_ALLIANCE].SelectedGroups;
    
  •   	GroupsQueueType hordepool = m_SelectionPools[TEAM_HORDE].SelectedGroups;
    
  •   	GroupQueueInfo* ginfo = itr->second;
    
  •   	// If player already was invited via pre adding (add to own team first) or he was already invited to a bg, skip.
    
  •   	if (ginfo->IsInvitedToBGInstanceGUID ||
    
  •   		std::find(allypool.begin(), allypool.end(), ginfo) != allypool.end() ||
    
  •   		std::find(hordepool.begin(), hordepool.end(), ginfo) != hordepool.end() ||
    
  •   		(m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() >= bg->GetMinPlayersPerTeam() &&
    
  •   		m_SelectionPools[TEAM_HORDE].GetPlayerCount() >= bg->GetMinPlayersPerTeam()))
    
  •   		continue;
    
  •   	diff = abs(valiFree - vhordeFree);
    
  •   	bool moreAli = valiFree < vhordeFree;
    
  •   	if (diff > 0)
    
  •   		ginfo->Team = moreAli ? HORDE : ALLIANCE;
    
  •   	bool alliance = ginfo->Team == ALLIANCE;
    
  •   	if (m_SelectionPools[alliance ? TEAM_ALLIANCE : TEAM_HORDE].AddGroup(ginfo, alliance ? aliFree : hordeFree))
    
  •   		alliance ? valiFree -= ginfo->Players.size() : vhordeFree -= ginfo->Players.size();
    
  •   }
    
  •   return true;
    
  • }
  • return false;
    +}

+int32 BattlegroundQueue::PreAddPlayers(QueuedGroupMap m_PreGroupMap, int32 MaxAdd, uint32 MaxInTeam)
+{

  • int32 LeftToAdd = MaxAdd;
  • uint32 Added = 0;
  • for (QueuedGroupMap::reverse_iterator itr = m_PreGroupMap.rbegin(); itr != m_PreGroupMap.rend(); ++itr)
  • {
  •   int32 PlayerSize = itr->first;
    
  •   bool alliance = itr->second->CFSTeam == ALLIANCE;
    
  •   if (PlayerSize <= LeftToAdd && m_SelectionPools[alliance ? TEAM_ALLIANCE : TEAM_HORDE].AddGroup(itr->second, MaxInTeam))
    
  •   	LeftToAdd -= PlayerSize, Added -= PlayerSize;
    
  • }
  • return LeftToAdd;
    +}

+void Player::SendChatMessage(const char *format, …)
+{

  • if (!IsInWorld())
  •   return;
    
  • if (format)
  • {
  •   va_list ap;
    
  •   char str[2048];
    
  •   va_start(ap, format);
    
  •   vsnprintf(str, 2048, format, ap);
    
  •   va_end(ap);
    
  •   ChatHandler(GetSession()).SendSysMessage(str);
    
  • }
    +}
    \ No newline at end of file
    diff --git a/src/server/game/Cfbg/Cfbg.h b/src/server/game/Cfbg/Cfbg.h
    new file mode 100644
    index 0000000…3f8285d
    — /dev/null
    +++ b/src/server/game/Cfbg/Cfbg.h
    @@ -0,0 +1,44 @@
    +/*
    • This program is free software; you can redistribute it and/or modify it
    • under the terms of the GNU General Public License as published by the
    • Free Software Foundation; either version 2 of the License, or (at your
    • option) any later version.
    • This program is distributed in the hope that it will be useful, but WITHOUT
    • ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    • FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
    • more details.
    • You should have received a copy of the GNU General Public License along

+#ifndef _CUSTOM_H
+#define _CUSTOM_H
+
+#define MSG_COLOR_LIGHTRED “|cffff6060”
+#define MSG_COLOR_LIGHTBLUE “|cff00ccff”
+#define MSG_COLOR_ANN_GREEN “|c1f40af20”
+#define MSG_COLOR_RED “|cffff0000”
+#define MSG_COLOR_GOLD “|cffffcc00”
+#define MSG_COLOR_SUBWHITE “|cffbbbbbb”
+#define MSG_COLOR_MAGENTA “|cffff00ff”
+#define MSG_COLOR_YELLOW “|cffffff00”
+#define MSG_COLOR_CYAN “|cff00ffff”
+#define MSG_COLOR_DARKBLUE “|cff0000ff”
+
+#define MSG_COLOR_GREY “|cff9d9d9d”
+#define MSG_COLOR_WHITE “|cffffffff”
+#define MSG_COLOR_GREEN “|cff1eff00”
+#define MSG_COLOR_BLUE “|cff0080ff”
+#define MSG_COLOR_PURPLE “|cffb048f8”
+#define MSG_COLOR_ORANGE “|cffff8000”
+
+#define MSG_COLOR_DRUID “|cffff7d0a”
+#define MSG_COLOR_HUNTER “|cffabd473”
+#define MSG_COLOR_MAGE “|cff69ccf0”
+#define MSG_COLOR_PALADIN “|cfff58cba”
+#define MSG_COLOR_PRIEST “|cffffffff”
+#define MSG_COLOR_ROGUE “|cfffff569”
+#define MSG_COLOR_SHAMAN “|cff0070de”
+#define MSG_COLOR_WARLOCK “|cff9482c9”
+#define MSG_COLOR_WARRIOR “|cffc79c6e”
+#define MSG_COLOR_DEATH_KNIGHT “|cffc41f3b”
+#define MSG_COLOR_MONK “|cff00ff96”
+
+#define LIMIT_UINT32 2147483647
+
+enum FakeMorphs
+{

  • FAKE_F_TAUREN = 20584,
  • FAKE_M_TAUREN = 20585,
  • FAKE_M_NELF = 20318,
  • FAKE_F_DRAENEI = 20323,
    +};

+#endif
\ No newline at end of file
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 8d7c800…52b6afb 100644
— a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -659,6 +659,12 @@ void KillRewarder::Reward()

Player::Player(WorldSession* session): Unit(true)
{

  • m_FakeRace = 0;
  • m_RealRace = 0;
  • m_FakeMorph = 0;
  • m_ForgetBGPlayers = false;
  • m_ForgetInListPlayers = false;
  • m_speakTime = 0;
    m_speakCount = 0;

@@ -1017,6 +1023,12 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo)
uint32 RaceClassGender = (createInfo->Race) | (createInfo->Class << 8) | (createInfo->Gender << 16);

 SetUInt32Value(UNIT_FIELD_BYTES_0, (RaceClassGender | (powertype << 24)));
  • SetCFSRace();

  • m_team = TeamForRace(getCFSRace());

  • SetFakeRaceAndMorph(); // m_team must be set before this can be used.

  • setFactionForRace(getCFSRace());

  • InitDisplayIds();
    if (sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP)
    {
    @@ -3055,7 +3067,7 @@ void Player::GiveLevel(uint8 level)
    guild->UpdateMemberData(this, GUILD_MEMBER_DATA_LEVEL, level);

    PlayerLevelInfo info;

  • sObjectMgr->GetPlayerLevelInfo(getRace(), getClass(), level, &info);
  • sObjectMgr->GetPlayerLevelInfo(getCFSRace(), getClass(), level, &info);

    PlayerClassLevelInfo classInfo;
    sObjectMgr->GetPlayerClassLevelInfo(getClass(), level, &classInfo);
    @@ -3193,7 +3205,7 @@ void Player::InitStatsForLevel(bool reapplyMods)
    sObjectMgr->GetPlayerClassLevelInfo(getClass(), getLevel(), &classInfo);

    PlayerLevelInfo info;

  • sObjectMgr->GetPlayerLevelInfo(getRace(), getClass(), getLevel(), &info);
  • sObjectMgr->GetPlayerLevelInfo(getCFSRace(), getClass(), getLevel(), &info);

    SetUInt32Value(PLAYER_FIELD_MAX_LEVEL, sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
    SetUInt32Value(PLAYER_NEXT_LEVEL_XP, sObjectMgr->GetXPForLevel(getLevel()));
    @@ -5256,7 +5268,7 @@ void Player::CreateCorpse()
    return;
    }

  • _uf = GetUInt32Value(UNIT_FIELD_BYTES_0);
  • _uf = getCFSRace();
    _pb = GetUInt32Value(PLAYER_BYTES);
    _pb2 = GetUInt32Value(PLAYER_BYTES_2);

@@ -6940,10 +6952,10 @@ uint32 Player::TeamForRace(uint8 race)

void Player::setFactionForRace(uint8 race)
{

  • m_team = TeamForRace(race);
  • SetBGTeam(TeamForRace(race));

    ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(race);

  • setFaction(rEntry ? rEntry->FactionID : 0);
  • setFaction(rEntry ? rEntry->FactionID : getFaction());
    }

ReputationRank Player::GetReputationRank(uint32 faction) const
@@ -7045,6 +7057,27 @@ void Player::RewardReputation(Unit* victim, float rate)
if (!Rep)
return;

  • uint32 repfaction1 = Rep->RepFaction1;

  • uint32 repfaction2 = Rep->RepFaction2;

  • if (!IsPlayingNative())

  • {

  •   if (GetCFSTeam() == ALLIANCE)
    
  •   {
    
  •   	if (repfaction1 == 729)
    
  •   		repfaction1 = 730;
    
  •   	if (repfaction2 == 729)
    
  •   		repfaction2 = 730;
    
  •   }
    
  •   else
    
  •   {
    
  •   	if (repfaction1 == 730)
    
  •   		repfaction1 = 729;
    
  •   	if (repfaction2 == 730)
    
  •   		repfaction2 = 729;
    
  •   }
    
  • }

  • uint32 ChampioningFaction = 0;

    if (GetChampioningFaction())
    @@ -7059,23 +7092,23 @@ void Player::RewardReputation(Unit* victim, float rate)

    uint32 team = GetTeam();

  • if (Rep->RepFaction1 && (!Rep->TeamDependent || team == ALLIANCE))
  • if (repfaction1 && (!Rep->TeamDependent || team == ALLIANCE))
    {
  •    int32 donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue1, ChampioningFaction ? ChampioningFaction : Rep->RepFaction1);
    
  •   int32 donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue1, ChampioningFaction ? ChampioningFaction : repfaction1);
       donerep1 = int32(donerep1 * rate);
    
  •    FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction1);
    
  •   FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : repfaction1);
       uint32 current_reputation_rank1 = GetReputationMgr().GetRank(factionEntry1);
       if (factionEntry1 && current_reputation_rank1 <= Rep->ReputationMaxCap1)
           GetReputationMgr().ModifyReputation(factionEntry1, donerep1);
    
    }
  • if (Rep->RepFaction2 && (!Rep->TeamDependent || team == HORDE))
  • if (repfaction2 && (!Rep->TeamDependent || team == HORDE))
    {
  •    int32 donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue2, ChampioningFaction ? ChampioningFaction : Rep->RepFaction2);
    
  •   int32 donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue2, ChampioningFaction ? ChampioningFaction : repfaction2);
       donerep2 = int32(donerep2 * rate);
    
  •    FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction2);
    
  •   FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : repfaction2);
       uint32 current_reputation_rank2 = GetReputationMgr().GetRank(factionEntry2);
       if (factionEntry2 && current_reputation_rank2 <= Rep->ReputationMaxCap2)
           GetReputationMgr().ModifyReputation(factionEntry2, donerep2);
    

@@ -7170,7 +7203,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto
if (!victim || victim == this || victim->GetTypeId() != TYPEID_PLAYER)
return false;

  •    if (GetBGTeam() == victim->ToPlayer()->GetBGTeam())
    
  •   if (GetTeam() == victim->ToPlayer()->GetTeam())
           return false;
    
       return true;
    

@@ -12055,13 +12088,13 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const
if (!proto)
return EQUIP_ERR_ITEM_NOT_FOUND;

  • if ((proto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && GetTeam() != HORDE)
  • if ((proto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && GetCFSTeam() != HORDE)
    return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
  • if ((proto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && GetTeam() != ALLIANCE)
  • if ((proto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && GetCFSTeam() != ALLIANCE)
    return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
  • if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getRaceMask()) == 0)
  • if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getCFSRaceMask()) == 0)
    return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;

    if (proto->RequiredSkill != 0)
    @@ -17321,6 +17354,11 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
    bytes0 |= gender << 16; // gender
    SetUInt32Value(UNIT_FIELD_BYTES_0, bytes0);

  • SetCFSRace(); //**** umisteni ****

  • m_team = TeamForRace(getCFSRace());

  • SetFakeRaceAndMorph(); // m_team must be set before this can be used.

  • setFactionForRace(getCFSRace());//Need to call it to initialize m_team (m_team can be calculated from race)

  • // check if race/class combination is valid
    PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
    if (!info)
    @@ -17389,10 +17427,6 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
    TC_LOG_DEBUG(“entities.player.loading”, "Load Basic value of player %s is: ", m_name.c_str());
    outDebugValues();

  • //Need to call it to initialize m_team (m_team can be calculated from race)
  • //Other way is to saves m_team into characters table.
  • setFactionForRace(getRace());
  • // load home bind and check in same time class/race pair, it used later for restore broken positions
    if (!_LoadHomeBind(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_HOME_BIND)))
    return false;
    @@ -19220,7 +19254,7 @@ void Player::AddInstanceEnterTime(uint32 instanceId, time_t enterTime)

bool Player::_LoadHomeBind(PreparedQueryResult result)
{

  • PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
  • PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getCFSRace(), getClass());
    if (!info)
    {
    TC_LOG_ERROR(“entities.player”, “Player (Name %s) has incorrect race/class pair. Can’t be loaded.”, GetName().c_str());
    @@ -19313,7 +19347,7 @@ void Player::SaveToDB(bool create /=false/)
    stmt->setUInt32(index++, GetGUIDLow());
    stmt->setUInt32(index++, GetSession()->GetAccountId());
    stmt->setString(index++, GetName());
  •    stmt->setUInt8(index++, getRace());
    
  •   stmt->setUInt8(index++, getCFSRace());
       stmt->setUInt8(index++, getClass());
       stmt->setUInt8(index++, getGender());
       stmt->setUInt8(index++, getLevel());
    

@@ -19418,7 +19452,7 @@ void Player::SaveToDB(bool create /=false/)
// Update query
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHARACTER);
stmt->setString(index++, GetName());

  •    stmt->setUInt8(index++, getRace());
    
  •    stmt->setUInt8(index++, getCFSRace());
       stmt->setUInt8(index++, getClass());
       stmt->setUInt8(index++, getGender());
       stmt->setUInt8(index++, getLevel());
    

@@ -21682,22 +21716,26 @@ void Player::InitDataForForm(bool reapplyMods)

void Player::InitDisplayIds()
{

  • PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
  • PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getCFSRace(), getClass());
    if (!info)
    {
    TC_LOG_ERROR(“entities.player”, “Player %u has incorrect race/class pair. Can’t init display ids.”, GetGUIDLow());
    return;
    }

  • bool isMorphed = GetNativeDisplayId() != GetDisplayId();

  • uint8 gender = getGender();
    switch (gender)
    {
    case GENDER_FEMALE:

  •        SetDisplayId(info->displayId_f);
    
  •   	if (!isMorphed)
    
  •   		SetDisplayId(info->displayId_f);
           SetNativeDisplayId(info->displayId_f);
           break;
       case GENDER_MALE:
    
  •        SetDisplayId(info->displayId_m);
    
  •   	if (!isMorphed)
    
  •   		SetDisplayId(info->displayId_m);
           SetNativeDisplayId(info->displayId_m);
           break;
       default:
    

@@ -22496,11 +22534,6 @@ void Player::SetBGTeam(uint32 team)
SetByteValue(PLAYER_BYTES_3, 3, uint8(team == ALLIANCE ? 1 : 0));
}

-uint32 Player::GetBGTeam() const
-{

  • return m_bgData.bgTeam ? m_bgData.bgTeam : GetTeam();
    -}

void Player::LeaveBattleground(bool teleportToEntryPoint)
{
if (Battleground* bg = GetBattleground())
@@ -22576,7 +22609,7 @@ void Player::ReportedAfkBy(Player* reporter)

WorldLocation Player::GetStartPosition() const
{

  • PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
  • PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getCFSRace(), getClass());
    uint32 mapId = info->mapId;
    if (getClass() == CLASS_DEATH_KNIGHT && HasSpell(50977))
    mapId = 0;
    @@ -23261,7 +23294,7 @@ void Player::LearnCustomSpells()
    for (PlayerCreateInfoSpells::const_iterator itr = info->customSpells.begin(); itr != info->customSpells.end(); ++itr)
    {
    uint32 tspell = *itr;
  •    TC_LOG_DEBUG("entities.player.loading", "PLAYER (Class: %u Race: %u): Adding initial spell, id = %u", uint32(getClass()), uint32(getRace()), tspell);
    
  •   TC_LOG_DEBUG("entities.player.loading", "PLAYER (Class: %u Race: %u): Adding initial spell, id = %u", uint32(getClass()), uint32(getCFSRace()), tspell);
       if (!IsInWorld())                                    // will send in INITIAL_SPELLS in list anyway at map add
           AddSpell(tspell, true, true, true, false);
       else                                                // but send in normal spell in game learn case
    

diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 313937a…0a4a939 100644
— a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1121,6 +1121,36 @@ class Player : public Unit, public GridObject
explicit Player(WorldSession* session);
~Player();

  • private:
  •   bool m_ForgetBGPlayers;
    
  •   bool m_ForgetInListPlayers;
    
  •   uint8 m_FakeRace;
    
  •   uint8 m_RealRace;
    
  •   uint32 m_FakeMorph;
    
  • public:
  •   typedef std::vector<uint64> FakePlayers;
    
  •   void SendChatMessage(const char *format, ...);
    
  •   void FitPlayerInTeam(bool action, Battleground* pBattleGround = NULL);		// void FitPlayerInTeam(bool action, Battleground* bg = NULL);
    
  •   void DoForgetPlayersInList();
    
  •   void DoForgetPlayersInBG(Battleground* pBattleGround);						// void DoForgetPlayersInBG(Battleground* bg);
    
  •   uint8 getCFSRace() const { return m_RealRace; }
    
  •   void SetCFSRace() { m_RealRace = GetByteValue(UNIT_FIELD_BYTES_0, 0); }; // SHOULD ONLY BE CALLED ON LOGIN
    
  •   void SetFakeRace(); // SHOULD ONLY BE CALLED ON LOGIN
    
  •   void SetFakeRaceAndMorph(); // SHOULD ONLY BE CALLED ON LOGIN
    
  •   uint32 GetFakeMorph() { return m_FakeMorph; };
    
  •   uint8 getFRace() const { return m_FakeRace; }
    
  •   void SetForgetBGPlayers(bool value) { m_ForgetBGPlayers = value; }
    
  •   bool ShouldForgetBGPlayers() { return m_ForgetBGPlayers; }
    
  •   void SetForgetInListPlayers(bool value) { m_ForgetInListPlayers = value; }
    
  •   bool ShouldForgetInListPlayers() { return m_ForgetInListPlayers; }
    
  •   bool SendBattleGroundChat(uint32 msgtype, std::string message);
    
  •   void MorphFit(bool value);
    
  •   bool IsPlayingNative() const { return GetTeam() == m_team; }
    
  •   uint32 GetCFSTeam() const { return m_team; }
    
  •   uint32 GetTeam() const { return m_bgData.bgTeam && GetBattleground() ? m_bgData.bgTeam : m_team; }
    
  •   bool SendRealNameQuery();
    
  •   FakePlayers m_FakePlayers;
    
  •    void CleanupsBeforeDelete(bool finalCleanup = true) override;
    
       void AddToWorld() override;
    

@@ -1174,7 +1204,7 @@ class Player : public Unit, public GridObject
PlayerSocial *GetSocial() { return m_social; }

     PlayerTaxi m_taxi;
  •    void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(), getClass(), getLevel()); }
    
  •   void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getCFSRace(), getClass(), getLevel()); }
       bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc = NULL, uint32 spellid = 0);
       bool ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid = 0);
       void CleanupAfterTaxiFlight();
    

@@ -1952,8 +1982,7 @@ class Player : public Unit, public GridObject
void CheckAreaExploreAndOutdoor(void);

     static uint32 TeamForRace(uint8 race);
  •    uint32 GetTeam() const { return m_team; }
    
  •    TeamId GetTeamId() const { return m_team == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; }
    
  •   TeamId GetTeamId() const { return GetTeam() == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; }
       void setFactionForRace(uint8 race);
    
       void InitDisplayIds();
    

@@ -2098,7 +2127,6 @@ class Player : public Unit, public GridObject
void SetBattlegroundEntryPoint();

     void SetBGTeam(uint32 team);
  •    uint32 GetBGTeam() const;
    
       void LeaveBattleground(bool teleportToEntryPoint = true);
       bool CanJoinToBattleground(Battleground const* bg) const;
    

diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 37f6950…0f7a4d3 100644
— a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -16773,6 +16773,21 @@ uint32 Unit::GetModelForTotem(PlayerTotemType totemType)
}
break;
}

  •   default: // One standard for other races.
    
  •   {
    
  •   	switch (totemType)
    
  •   	{
    
  •   		case SUMMON_TYPE_TOTEM_FIRE:    // fire
    
  •   			return 4589;
    
  •   		case SUMMON_TYPE_TOTEM_EARTH:   // earth
    
  •   			return 4588;
    
  •   		case SUMMON_TYPE_TOTEM_WATER:   // water
    
  •   			return 4587;
    
  •   		case SUMMON_TYPE_TOTEM_AIR:     // air
    
  •   			return 4590;
    
  •   	}
    
  •   	break;
    
  •   }
    
    }
    return 0;
    }
    diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
    index 20344fb…566d755 100644
    — a/src/server/game/Entities/Unit/Unit.h
    +++ b/src/server/game/Entities/Unit/Unit.h
    @@ -1356,8 +1356,10 @@ class Unit : public WorldObject
    uint8 getLevel() const { return uint8(GetUInt32Value(UNIT_FIELD_LEVEL)); }
    uint8 getLevelForTarget(WorldObject const* /target/) const override { return getLevel(); }
    void SetLevel(uint8 lvl);
  •    uint8 getRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, 0); }
    
  •   uint8 getRace(bool forceoriginal = false) const;
    
  •   uint8 getCFSRace() { return getRace(true); }
       uint32 getRaceMask() const { return 1 << (getRace()-1); }
    
  •   uint32 getCFSRaceMask() const { return 1 << (getRace(true) - 1); }
       uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, 1); }
       uint32 getClassMask() const { return 1 << (getClass()-1); }
       uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, 2); }
    

diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp
index 7f28fc8…be9285d 100644
— a/src/server/game/Handlers/BattleGroundHandler.cpp
+++ b/src/server/game/Handlers/BattleGroundHandler.cpp
@@ -543,7 +543,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /recvData/)
{
// this line is checked, i only don’t know if GetStartTime is changing itself after bg end!
// send status in Battleground

  •            sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetBGTeam());
    
  •            sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetTeam());
               SendPacket(&data);
               continue;
           }
    

diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 7df4065…970af65 100644
— a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -994,6 +994,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
sScriptMgr->OnPlayerLogin(pCurrChar, firstLogin);

 delete holder;
  • if (pCurrChar->GetTeam() != pCurrChar->GetCFSTeam())
  •   pCurrChar->FitPlayerInTeam(pCurrChar->GetBattleground() && !pCurrChar->GetBattleground()->isArena() ? true : false, pCurrChar->GetBattleground());
    

}

void WorldSession::HandleSetFactionAtWar(WorldPacket& recvData)
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index a583133…a6e04d9 100644
— a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -252,6 +252,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
return;
}

  •   	if (!GetPlayer()->IsGameMaster())
    
  •   	if (GetPlayer()->SendBattleGroundChat(type, msg))
    
  •   		return;
    
  •        if (type == CHAT_MSG_SAY)
               sender->Say(msg, Language(lang));
           else if (type == CHAT_MSG_EMOTE)
    

diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 49f251e…959df74 100644
— a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -1421,6 +1421,21 @@ void WorldSession::HandleSetTitleOpcode(WorldPacket& recvData)

void WorldSession::HandleTimeSyncResp(WorldPacket& recvData)
{

  • Battleground* bg = _player->GetBattleground();

  • if (bg)

  • {

  •   if (_player->ShouldForgetBGPlayers() && bg)
    
  •   {
    
  •   	_player->DoForgetPlayersInBG(bg);
    
  •   	_player->SetForgetBGPlayers(false);
    
  •   }
    
  • }

  • else if (_player->ShouldForgetInListPlayers())

  • {

  •   _player->DoForgetPlayersInList();
    
  •   _player->SetForgetInListPlayers(false);
    
  • }

  • TC_LOG_DEBUG(“network”, “CMSG_TIME_SYNC_RESP”);

    uint32 counter, clientTicks;
    diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
    index 9e2b497…dbb01f1 100644
    — a/src/server/game/Handlers/QueryHandler.cpp
    +++ b/src/server/game/Handlers/QueryHandler.cpp
    @@ -46,7 +46,7 @@ void WorldSession::SendNameQueryOpcode(ObjectGuid guid)
    data << uint8(0); // name known
    data << nameData->m_name; // played name
    data << uint8(0); // realm name - only set for cross realm interaction (such as Battlegrounds)

  • data << uint8(nameData->m_race);
  • data << uint8(player ? player->getRace() : nameData->m_race);
    data << uint8(nameData->m_gender);
    data << uint8(nameData->m_class);

diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index e28b74d…bc9534f 100644
— a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1058,6 +1058,8 @@ void World::LoadConfigSettings(bool reload)

 m_bool_configs[CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN]            = sConfigMgr->GetBoolDefault("OffhandCheckAtSpellUnlearn", true);
  • m_bool_configs[CROSSFACTION_SYSTEM_BATTLEGROUNDS] = sConfigMgr->GetBoolDefault(“CrossFactionSystem.Battlegrounds”, true);

  • m_int_configs[CONFIG_CREATURE_PICKPOCKET_REFILL] = sConfigMgr->GetIntDefault(“Creature.PickPocketRefillDelay”, 10 * MINUTE);

    if (int32 clientCacheId = sConfigMgr->GetIntDefault(“ClientCacheVersion”, 0))
    diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
    index 26d6029…7ece36e 100644
    — a/src/server/game/World/World.h
    +++ b/src/server/game/World/World.h
    @@ -86,6 +86,7 @@ enum WorldTimers
    enum WorldBoolConfigs
    {
    CONFIG_DURABILITY_LOSS_IN_PVP = 0,

  • CROSSFACTION_SYSTEM_BATTLEGROUNDS,
    CONFIG_ADDON_CHANNEL,
    CONFIG_ALLOW_PLAYER_COMMANDS,
    CONFIG_CLEAN_CHARACTER_DB,
    diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
    index 08983a5…b037b5f 100644
    — a/src/server/worldserver/worldserver.conf.dist
    +++ b/src/server/worldserver/worldserver.conf.dist
    @@ -3412,3 +3412,15 @@ PacketSpoof.BanDuration = 86400

###################################################################################################
+
+###################################################################################################
+#
+# CROSSFACTION SYSTEM
+#
+# CrossFactionSystem.Battlegrounds = 1 - Mixed battleground enabled.
+# CrossFactionSystem.Battlegrounds = 0 - Mixed battleground disabled.
+
+CrossFactionSystem.Battlegrounds = 1
+
+#
+###################################################################################################
\ No newline at end of file

1.9.4.msysgit.2

Anti-Hacker Passivo - Última Revisão - Código Abaixo:

From 75cc6f92f1641a90c878c172ae15e873b33a8331 Mon Sep 17 00:00:00 2001
From: Noffearr [email protected]
Date: Thu, 7 May 2015 08:01:26 -0400
Subject: [PATCH] * Adicionado e Fixado Sistema Anticheat / Antihacker


…/Anticheat/characters.anticheat.sql | 30 ++
src/server/game/Anticheat/AnticheatData.cpp | 118 ++++++
src/server/game/Anticheat/AnticheatData.h | 63 +++
src/server/game/Anticheat/AnticheatMgr.cpp | 434 +++++++++++++++++++++
src/server/game/Anticheat/AnticheatMgr.h | 103 +++++
src/server/game/Anticheat/AnticheatScripts.cpp | 14 +
src/server/game/Anticheat/AnticheatScripts.h | 15 +
src/server/game/CMakeLists.txt | 3 +
src/server/game/Entities/Player/Player.cpp | 7 +
src/server/game/Entities/Unit/Unit.cpp | 4 +
src/server/game/Handlers/MovementHandler.cpp | 4 +
src/server/game/Scripting/ScriptLoader.cpp | 4 +
src/server/game/Spells/SpellEffects.cpp | 1 +
src/server/game/World/World.cpp | 8 +
src/server/game/World/World.h | 4 +
src/server/scripts/CMakeLists.txt | 1 +
src/server/scripts/Commands/cs_anticheat.cpp | 262 +++++++++++++
src/server/worldserver/worldserver.conf.dist | 34 ++
18 files changed, 1109 insertions(+)
create mode 100644 sql/TrinityCore-Patches/Anticheat/characters.anticheat.sql
create mode 100644 src/server/game/Anticheat/AnticheatData.cpp
create mode 100644 src/server/game/Anticheat/AnticheatData.h
create mode 100644 src/server/game/Anticheat/AnticheatMgr.cpp
create mode 100644 src/server/game/Anticheat/AnticheatMgr.h
create mode 100644 src/server/game/Anticheat/AnticheatScripts.cpp
create mode 100644 src/server/game/Anticheat/AnticheatScripts.h
create mode 100644 src/server/scripts/Commands/cs_anticheat.cpp

diff --git a/sql/TrinityCore-Patches/Anticheat/characters.anticheat.sql b/sql/TrinityCore-Patches/Anticheat/characters.anticheat.sql
new file mode 100644
index 0000000…3504594
— /dev/null
+++ b/sql/TrinityCore-Patches/Anticheat/characters.anticheat.sql
@@ -0,0 +1,30 @@
+DROP TABLE IF EXISTS players_reports_status;
+
+CREATE TABLE players_reports_status (

  • guid int(10) unsigned NOT NULL DEFAULT ‘0’,
  • creation_time int(10) unsigned NOT NULL DEFAULT ‘0’,
  • average float NOT NULL DEFAULT ‘0’,
  • total_reports bigint(20) unsigned NOT NULL DEFAULT ‘0’,
  • speed_reports bigint(20) unsigned NOT NULL DEFAULT ‘0’,
  • fly_reports bigint(20) unsigned NOT NULL DEFAULT ‘0’,
  • jump_reports bigint(20) unsigned NOT NULL DEFAULT ‘0’,
  • waterwalk_reports bigint(20) unsigned NOT NULL DEFAULT ‘0’,
  • teleportplane_reports bigint(20) unsigned NOT NULL DEFAULT ‘0’,
  • climb_reports bigint(20) unsigned NOT NULL DEFAULT ‘0’,
  • PRIMARY KEY (guid)
    +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=‘’;

+DROP TABLE IF EXISTS daily_players_reports;
+CREATE TABLE daily_players_reports (

  • guid int(10) unsigned NOT NULL DEFAULT ‘0’,
  • creation_time int(10) unsigned NOT NULL DEFAULT ‘0’,
  • average float NOT NULL DEFAULT ‘0’,
  • total_reports bigint(20) unsigned NOT NULL DEFAULT ‘0’,
  • speed_reports bigint(20) unsigned NOT NULL DEFAULT ‘0’,
  • fly_reports bigint(20) unsigned NOT NULL DEFAULT ‘0’,
  • jump_reports bigint(20) unsigned NOT NULL DEFAULT ‘0’,
  • waterwalk_reports bigint(20) unsigned NOT NULL DEFAULT ‘0’,
  • teleportplane_reports bigint(20) unsigned NOT NULL DEFAULT ‘0’,
  • climb_reports bigint(20) unsigned NOT NULL DEFAULT ‘0’,
  • PRIMARY KEY (guid)
    +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=‘’;
    \ No newline at end of file
    diff --git a/src/server/game/Anticheat/AnticheatData.cpp b/src/server/game/Anticheat/AnticheatData.cpp
    new file mode 100644
    index 0000000…8c69972
    — /dev/null
    +++ b/src/server/game/Anticheat/AnticheatData.cpp
    @@ -0,0 +1,118 @@
    +/*
    • This program is free software; you can redistribute it and/or modify it
    • under the terms of the GNU General Public License as published by the
    • Free Software Foundation; either version 2 of the License, or (at your
    • option) any later version.
    • This program is distributed in the hope that it will be useful, but WITHOUT
    • ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    • FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
    • more details.
    • You should have received a copy of the GNU General Public License along
  • */

+#include “AnticheatData.h”
+
+AnticheatData::AnticheatData()
+{

  • lastOpcode = 0;
  • totalReports = 0;
  • for (uint8 i = 0; i < MAX_REPORT_TYPES; i++)
  • {
  •    typeReports[i] = 0;
    
  •    tempReports[i] = 0;
    
  •    tempReportsTimer[i] = 0;
    
  • }
  • average = 0;
  • creationTime = 0;
  • hasDailyReport = false;
    +}

+AnticheatData::~AnticheatData()
+{
+}
+
+void AnticheatData::SetDailyReportState(bool b)
+{

  • hasDailyReport = b;
    +}

+bool AnticheatData::GetDailyReportState()
+{

  • return hasDailyReport;
    +}

+void AnticheatData::SetLastOpcode(uint32 opcode)
+{

  • lastOpcode = opcode;
    +}

+void AnticheatData::SetPosition(float x, float y, float z, float o)
+{

  • lastMovementInfo.pos.m_positionX = x;
  • lastMovementInfo.pos.m_positionY = y;
  • lastMovementInfo.pos.m_positionZ = z;
  • lastMovementInfo.pos.m_orientation = o;
    +}

+uint32 AnticheatData::GetLastOpcode() const
+{

  • return lastOpcode;
    +}

+const MovementInfo& AnticheatData::GetLastMovementInfo() const
+{

  • return lastMovementInfo;
    +}

+void AnticheatData::SetLastMovementInfo(MovementInfo& moveInfo)
+{

  • lastMovementInfo = moveInfo;
    +}

+uint32 AnticheatData::GetTotalReports() const
+{

  • return totalReports;
    +}

+void AnticheatData::SetTotalReports(uint32 _totalReports)
+{

  • totalReports = _totalReports;
    +}

+void AnticheatData::SetTypeReports(uint32 type, uint32 amount)
+{

  • typeReports[type] = amount;
    +}

+uint32 AnticheatData::GetTypeReports(uint32 type) const
+{

  • return typeReports[type];
    +}

+float AnticheatData::GetAverage() const
+{

  • return average;
    +}

+void AnticheatData::SetAverage(float _average)
+{

  • average = _average;
    +}

+uint32 AnticheatData::GetCreationTime() const
+{

  • return creationTime;
    +}

+void AnticheatData::SetCreationTime(uint32 _creationTime)
+{

  • creationTime = _creationTime;
    +}

+void AnticheatData::SetTempReports(uint32 amount, uint8 type)
+{

  • tempReports[type] = amount;
    +}

+uint32 AnticheatData::GetTempReports(uint8 type)
+{

  • return tempReports[type];
    +}

+void AnticheatData::SetTempReportsTimer(uint32 time, uint8 type)
+{

  • tempReportsTimer[type] = time;
    +}

+uint32 AnticheatData::GetTempReportsTimer(uint8 type)
+{

  • return tempReportsTimer[type];
    +}
    diff --git a/src/server/game/Anticheat/AnticheatData.h b/src/server/game/Anticheat/AnticheatData.h
    new file mode 100644
    index 0000000…700ad2d
    — /dev/null
    +++ b/src/server/game/Anticheat/AnticheatData.h
    @@ -0,0 +1,63 @@
    +/*
    • This program is free software; you can redistribute it and/or modify it
    • under the terms of the GNU General Public License as published by the
    • Free Software Foundation; either version 2 of the License, or (at your
    • option) any later version.
    • This program is distributed in the hope that it will be useful, but WITHOUT
    • ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    • FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
    • more details.
    • You should have received a copy of the GNU General Public License along
  • */

+#ifndef SC_ACDATA_H
+#define SC_ACDATA_H
+
+#include “AnticheatMgr.h”
+
+#define MAX_REPORT_TYPES 6
+
+class AnticheatData
+{
+public:

  • AnticheatData();
  • ~AnticheatData();
  • void SetLastOpcode(uint32 opcode);
  • uint32 GetLastOpcode() const;
  • const MovementInfo& GetLastMovementInfo() const;
  • void SetLastMovementInfo(MovementInfo& moveInfo);
  • void SetPosition(float x, float y, float z, float o);
  • /*
  • bool GetDisableACCheck() const;
  • void SetDisableACCheck(bool check);
  • uint32 GetDisableACTimer() const;
  • void SetDisableACTimer(uint32 timer);*/
  • uint32 GetTotalReports() const;
  • void SetTotalReports(uint32 _totalReports);
  • uint32 GetTypeReports(uint32 type) const;
  • void SetTypeReports(uint32 type, uint32 amount);
  • float GetAverage() const;
  • void SetAverage(float _average);
  • uint32 GetCreationTime() const;
  • void SetCreationTime(uint32 creationTime);
  • void SetTempReports(uint32 amount, uint8 type);
  • uint32 GetTempReports(uint8 type);
  • void SetTempReportsTimer(uint32 time, uint8 type);
  • uint32 GetTempReportsTimer(uint8 type);
  • void SetDailyReportState(bool b);
  • bool GetDailyReportState();
    +private:
  • uint32 lastOpcode;
  • MovementInfo lastMovementInfo;
  • //bool disableACCheck;
  • //uint32 disableACCheckTimer;
  • uint32 totalReports;
  • uint32 typeReports[MAX_REPORT_TYPES];
  • float average;
  • uint32 creationTime;
  • uint32 tempReports[MAX_REPORT_TYPES];
  • uint32 tempReportsTimer[MAX_REPORT_TYPES];
  • bool hasDailyReport;
    +};

+#endif
\ No newline at end of file
diff --git a/src/server/game/Anticheat/AnticheatMgr.cpp b/src/server/game/Anticheat/AnticheatMgr.cpp
new file mode 100644
index 0000000…f409e93
— /dev/null
+++ b/src/server/game/Anticheat/AnticheatMgr.cpp
@@ -0,0 +1,434 @@
+/*

    • This program is free software; you can redistribute it and/or modify it
    • under the terms of the GNU General Public License as published by the
    • Free Software Foundation; either version 2 of the License, or (at your
    • option) any later version.
    • This program is distributed in the hope that it will be useful, but WITHOUT
    • ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    • FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
    • more details.
    • You should have received a copy of the GNU General Public License along
  • */

+#include “AnticheatMgr.h”
+#include “AnticheatScripts.h”
+#include “MapManager.h”
+
+#define CLIMB_ANGLE 1.9f
+
+AnticheatMgr::AnticheatMgr()
+{
+}
+
+AnticheatMgr::~AnticheatMgr()
+{

  • m_Players.clear();
    +}

+void AnticheatMgr::JumpHackDetection(Player* player, MovementInfo /* movementInfo */,uint32 opcode)
+{

  • if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & JUMP_HACK_DETECTION) == 0)
  •    return;
    
  • uint32 key = player->GetGUIDLow();
  • if (m_Players[key].GetLastOpcode() == MSG_MOVE_JUMP && opcode == MSG_MOVE_JUMP)
  • {
  •    BuildReport(player,JUMP_HACK_REPORT);
    
  •    TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Jump-Hack detected player GUID (low) %u",player->GetGUIDLow());
    
  • }
    +}

+void AnticheatMgr::WalkOnWaterHackDetection(Player* player, MovementInfo /* movementInfo */)
+{

  • if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & WALK_WATER_HACK_DETECTION) == 0)
  •    return;
    
  • uint32 key = player->GetGUIDLow();
  • if (!m_Players[key].GetLastMovementInfo().HasMovementFlag(MOVEMENTFLAG_WATERWALKING))
  •    return;
    
  • // if we are a ghost we can walk on water
  • if (!player->IsAlive())
  •    return;
    
  • if (player->HasAuraType(SPELL_AURA_FEATHER_FALL) ||
  •    player->HasAuraType(SPELL_AURA_SAFE_FALL) ||
    
  •    player->HasAuraType(SPELL_AURA_WATER_WALK))
    
  •    return;
    
  • TC_LOG_DEBUG(“entities.player.character”, “AnticheatMgr:: Walk on Water - Hack detected player GUID (low) %u”,player->GetGUIDLow());
  • BuildReport(player,WALK_WATER_HACK_REPORT);

+}
+
+void AnticheatMgr::FlyHackDetection(Player* player, MovementInfo /* movementInfo */)
+{

  • if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & FLY_HACK_DETECTION) == 0)
  •    return;
    
  • uint32 key = player->GetGUIDLow();
  • if (!m_Players[key].GetLastMovementInfo().HasMovementFlag(MOVEMENTFLAG_FLYING))
  •    return;
    
  • if (player->HasAuraType(SPELL_AURA_FLY) ||
  •    player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) ||
    
  •    player->HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED))
    
  •    return;
    
  • TC_LOG_DEBUG(“entities.player.character”, “AnticheatMgr:: Fly-Hack detected player GUID (low) %u”,player->GetGUIDLow());
  • BuildReport(player,FLY_HACK_REPORT);
    +}

+void AnticheatMgr::TeleportPlaneHackDetection(Player* player, MovementInfo movementInfo)
+{

  • if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & TELEPORT_PLANE_HACK_DETECTION) == 0)
  •    return;
    
  • uint32 key = player->GetGUIDLow();
  • if (m_Players[key].GetLastMovementInfo().pos.GetPositionZ() != 0 ||
  •    movementInfo.pos.GetPositionZ() != 0)
    
  •    return;
    
  • if (movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING))
  •    return;
    
  • //DEAD_FALLING was deprecated
  • //if (player->getDeathState() == DEAD_FALLING)
  • // return;
  • float x, y, z;
  • player->GetPosition(x, y, z);
  • float ground_Z = player->GetMap()->GetHeight(x, y, z);
  • float z_diff = fabs(ground_Z - z);
  • // we are not really walking there
  • if (z_diff > 1.0f)
  • {
  •    TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Teleport To Plane - Hack detected player GUID (low) %u",player->GetGUIDLow());
    
  •    BuildReport(player,TELEPORT_PLANE_HACK_REPORT);
    
  • }
    +}

+void AnticheatMgr::StartHackDetection(Player* player, MovementInfo movementInfo, uint32 opcode)
+{

  • if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
  •    return;
    
  • if (player->IsGameMaster())
  •    return;
    
  • uint32 key = player->GetGUIDLow();
  • if (player->IsInFlight() || player->GetTransport() || player->GetVehicle())
  • {
  •    m_Players[key].SetLastMovementInfo(movementInfo);
    
  •    m_Players[key].SetLastOpcode(opcode);
    
  •    return;
    
  • }
  • SpeedHackDetection(player,movementInfo);
  • FlyHackDetection(player,movementInfo);
  • WalkOnWaterHackDetection(player,movementInfo);
  • JumpHackDetection(player,movementInfo,opcode);
  • TeleportPlaneHackDetection(player, movementInfo);
  • ClimbHackDetection(player,movementInfo,opcode);
  • m_Players[key].SetLastMovementInfo(movementInfo);
  • m_Players[key].SetLastOpcode(opcode);
    +}

+// basic detection
+void AnticheatMgr::ClimbHackDetection(Player *player, MovementInfo movementInfo, uint32 opcode)
+{

  • if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & CLIMB_HACK_DETECTION) == 0)
  •    return;
    
  • uint32 key = player->GetGUIDLow();
  • if (opcode != MSG_MOVE_HEARTBEAT ||
  •    m_Players[key].GetLastOpcode() != MSG_MOVE_HEARTBEAT)
    
  •    return;
    
  • // in this case we don’t care if they are “legal” flags, they are handled in another parts of the Anticheat Manager.
  • if (player->IsInWater() ||
  •    player->IsFlying() ||
    
  •    player->IsFalling())
    
  •    return;
    
  • Position playerPos;
  • Position pos = player->GetPosition();
  • float deltaZ = fabs(playerPos.GetPositionZ() - movementInfo.pos.GetPositionZ());
  • float deltaXY = movementInfo.pos.GetExactDist2d(&playerPos);
  • float angle = Position::NormalizeOrientation(tan(deltaZ/deltaXY));
  • if (angle > CLIMB_ANGLE)
  • {
  •    TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Climb-Hack detected player GUID (low) %u", player->GetGUIDLow());
    
  •    BuildReport(player,CLIMB_HACK_REPORT);
    
  • }
    +}

+void AnticheatMgr::SpeedHackDetection(Player* player,MovementInfo movementInfo)
+{

  • if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & SPEED_HACK_DETECTION) == 0)
  •    return;
    
  • uint32 key = player->GetGUIDLow();
  • // We also must check the map because the movementFlag can be modified by the client.
  • // If we just check the flag, they could always add that flag and always skip the speed hacking detection.
  • // 369 == DEEPRUN TRAM
  • if (m_Players[key].GetLastMovementInfo().HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && player->GetMapId() == 369)
  •    return;
    
  • uint32 distance2D = (uint32)movementInfo.pos.GetExactDist2d(&m_Players[key].GetLastMovementInfo().pos);
  • uint8 moveType = 0;
  • // we need to know HOW is the player moving
  • // TO-DO: Should we check the incoming movement flags?
  • if (player->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING))
  •    moveType = MOVE_SWIM;
    
  • else if (player->IsFlying())
  •    moveType = MOVE_FLIGHT;
    
  • else if (player->HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
  •    moveType = MOVE_WALK;
    
  • else
  •    moveType = MOVE_RUN;
    
  • // how many yards the player can do in one sec.
  • uint32 speedRate = (uint32)(player->GetSpeed(UnitMoveType(moveType)) + movementInfo.jump.xyspeed);
  • // how long the player took to move to here.
  • uint32 timeDiff = getMSTimeDiff(m_Players[key].GetLastMovementInfo().time,movementInfo.time);
  • if (!timeDiff)
  •    timeDiff = 1;
    
  • // this is the distance doable by the player in 1 sec, using the time done to move to this point.
  • uint32 clientSpeedRate = distance2D * 1000 / timeDiff;
  • // we did the (uint32) cast to accept a margin of tolerance
  • if (clientSpeedRate > speedRate)
  • {
  •    BuildReport(player,SPEED_HACK_REPORT);
    
  •    TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Speed-Hack detected player GUID (low) %u",player->GetGUIDLow());
    
  • }
    +}

+void AnticheatMgr::StartScripts()
+{

  • new AnticheatScripts();
    +}

+void AnticheatMgr::HandlePlayerLogin(Player* player)
+{

  • // we must delete this to prevent errors in case of crash
  • CharacterDatabase.PExecute(“DELETE FROM players_reports_status WHERE guid=%u”,player->GetGUIDLow());
  • // we initialize the pos of lastMovementPosition var.
  • m_Players[player->GetGUIDLow()].SetPosition(player->GetPositionX(),player->GetPositionY(),player->GetPositionZ(),player->GetOrientation());
  • QueryResult resultDB = CharacterDatabase.PQuery(“SELECT * FROM daily_players_reports WHERE guid=%u;”,player->GetGUIDLow());
  • if (resultDB)
  •    m_Players[player->GetGUIDLow()].SetDailyReportState(true);
    

+}
+
+void AnticheatMgr::HandlePlayerLogout(Player* player)
+{

  • // TO-DO Make a table that stores the cheaters of the day, with more detailed information.
  • // We must also delete it at logout to prevent have data of offline players in the db when we query the database (IE: The GM Command)
  • CharacterDatabase.PExecute(“DELETE FROM players_reports_status WHERE guid=%u”,player->GetGUIDLow());
  • // Delete not needed data from the memory.
  • m_Players.erase(player->GetGUIDLow());
    +}

+void AnticheatMgr::SavePlayerData(Player* player)
+{

  • CharacterDatabase.PExecute(“REPLACE INTO players_reports_status (guid,average,total_reports,speed_reports,fly_reports,jump_reports,waterwalk_reports,teleportplane_reports,climb_reports,creation_time) VALUES (%u,%f,%u,%u,%u,%u,%u,%u,%u,%u);”,player->GetGUIDLow(),m_Players[player->GetGUIDLow()].GetAverage(),m_Players[player->GetGUIDLow()].GetTotalReports(), m_Players[player->GetGUIDLow()].GetTypeReports(SPEED_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(FLY_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(JUMP_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(WALK_WATER_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(TELEPORT_PLANE_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(CLIMB_HACK_REPORT),m_Players[player->GetGUIDLow()].GetCreationTime());
    +}

+uint32 AnticheatMgr::GetTotalReports(uint32 lowGUID)
+{

  • return m_Players[lowGUID].GetTotalReports();
    +}

+float AnticheatMgr::GetAverage(uint32 lowGUID)
+{

  • return m_Players[lowGUID].GetAverage();
    +}

+uint32 AnticheatMgr::GetTypeReports(uint32 lowGUID, uint8 type)
+{

  • return m_Players[lowGUID].GetTypeReports(type);
    +}

+bool AnticheatMgr::MustCheckTempReports(uint8 type)
+{

  • if (type == JUMP_HACK_REPORT)
  •    return false;
    
  • return true;
    +}

+void AnticheatMgr::BuildReport(Player* player,uint8 reportType)
+{

  • uint32 key = player->GetGUIDLow();
  • if (MustCheckTempReports(reportType))
  • {
  •    uint32 actualTime = getMSTime();
    
  •    if (!m_Players[key].GetTempReportsTimer(reportType))
    
  •        m_Players[key].SetTempReportsTimer(actualTime,reportType);
    
  •    if (getMSTimeDiff(m_Players[key].GetTempReportsTimer(reportType),actualTime) < 3000)
    
  •    {
    
  •        m_Players[key].SetTempReports(m_Players[key].GetTempReports(reportType)+1,reportType);
    
  •        if (m_Players[key].GetTempReports(reportType) < 3)
    
  •            return;
    
  •    } else
    
  •    {
    
  •        m_Players[key].SetTempReportsTimer(actualTime,reportType);
    
  •        m_Players[key].SetTempReports(1,reportType);
    
  •        return;
    
  •    }
    
  • }
  • // generating creationTime for average calculation
  • if (!m_Players[key].GetTotalReports())
  •    m_Players[key].SetCreationTime(getMSTime());
    
  • // increasing total_reports
  • m_Players[key].SetTotalReports(m_Players[key].GetTotalReports()+1);
  • // increasing specific cheat report
  • m_Players[key].SetTypeReports(reportType,m_Players[key].GetTypeReports(reportType)+1);
  • // diff time for average calculation
  • uint32 diffTime = getMSTimeDiff(m_Players[key].GetCreationTime(),getMSTime()) / IN_MILLISECONDS;
  • if (diffTime > 0)
  • {
  •    // Average == Reports per second
    
  •    float average = float(m_Players[key].GetTotalReports()) / float(diffTime);
    
  •    m_Players[key].SetAverage(average);
    
  • }
  • if (sWorld->getIntConfig(CONFIG_ANTICHEAT_MAX_REPORTS_FOR_DAILY_REPORT) < m_Players[key].GetTotalReports())
  • {
  •    if (!m_Players[key].GetDailyReportState())
    
  •    {
    
  •        CharacterDatabase.PExecute("REPLACE INTO daily_players_reports (guid,average,total_reports,speed_reports,fly_reports,jump_reports,waterwalk_reports,teleportplane_reports,climb_reports,creation_time) VALUES (%u,%f,%u,%u,%u,%u,%u,%u,%u,%u);",player->GetGUIDLow(),m_Players[player->GetGUIDLow()].GetAverage(),m_Players[player->GetGUIDLow()].GetTotalReports(), m_Players[player->GetGUIDLow()].GetTypeReports(SPEED_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(FLY_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(JUMP_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(WALK_WATER_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(TELEPORT_PLANE_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(CLIMB_HACK_REPORT),m_Players[player->GetGUIDLow()].GetCreationTime());
    
  •        m_Players[key].SetDailyReportState(true);
    
  •    }
    
  • }
  • if (m_Players[key].GetTotalReports() > sWorld->getIntConfig(CONFIG_ANTICHEAT_REPORTS_INGAME_NOTIFICATION))
  • {
  •    // display warning at the center of the screen, hacky way?
    
  •    std::string str = "";
    
  •    str = "|cFFFFFC00[AC]|cFF00FFFF[|cFF60FF00" + std::string(player->GetName().c_str()) + "|cFF00FFFF] Possible cheater!";
    
  •    WorldPacket data(SMSG_NOTIFICATION, (str.size()+1));
    
  •    data << str;
    
  •    sWorld->SendGlobalGMMessage(&data);
    
  • }
    +}

+void AnticheatMgr::AnticheatGlobalCommand(ChatHandler* handler)
+{

  • // MySQL will sort all for us, anyway this is not the best way we must only save the anticheat data not whole player’s data!.
  • sObjectAccessor->SaveAllPlayers();
  • QueryResult resultDB = CharacterDatabase.Query(“SELECT guid,average,total_reports FROM players_reports_status WHERE total_reports != 0 ORDER BY average ASC LIMIT 3;”);
  • if (!resultDB)
  • {
  •    handler->PSendSysMessage("No players found.");
    
  •    return;
    
  • } else
  • {
  •    handler->SendSysMessage("=============================");
    
  •    handler->PSendSysMessage("Players with the lowest averages:");
    
  •    do
    
  •    {
    
  •        Field *fieldsDB = resultDB->Fetch();
    
  •        uint32 guid = fieldsDB[0].GetUInt32();
    
  •        float average = fieldsDB[1].GetFloat();
    
  •        uint32 total_reports = fieldsDB[2].GetUInt32();
    
  •        if (Player* player = sObjectMgr->GetPlayerByLowGUID(guid))
    
  •            handler->PSendSysMessage("Player: %s Average: %f Total Reports: %u",player->GetName().c_str(),average,total_reports);
    
  •    } while (resultDB->NextRow());
    
  • }
  • resultDB = CharacterDatabase.Query(“SELECT guid,average,total_reports FROM players_reports_status WHERE total_reports != 0 ORDER BY total_reports DESC LIMIT 3;”);
  • // this should never happen
  • if (!resultDB)
  • {
  •    handler->PSendSysMessage("No players found.");
    
  •    return;
    
  • } else
  • {
  •    handler->SendSysMessage("=============================");
    
  •    handler->PSendSysMessage("Players with the more reports:");
    
  •    do
    
  •    {
    
  •        Field *fieldsDB = resultDB->Fetch();
    
  •        uint32 guid = fieldsDB[0].GetUInt32();
    
  •        float average = fieldsDB[1].GetFloat();
    
  •        uint32 total_reports = fieldsDB[2].GetUInt32();
    
  •        if (Player* player = sObjectMgr->GetPlayerByLowGUID(guid))
    
  •            handler->PSendSysMessage("Player: %s Total Reports: %u Average: %f",player->GetName().c_str(),total_reports,average);
    
  •    } while (resultDB->NextRow());
    
  • }
    +}

+void AnticheatMgr::AnticheatDeleteCommand(uint32 guid)
+{

  • if (!guid)
  • {
  •    for (AnticheatPlayersDataMap::iterator it = m_Players.begin(); it != m_Players.end(); ++it)
    
  •    {
    
  •        (*it).second.SetTotalReports(0);
    
  •        (*it).second.SetAverage(0);
    
  •        (*it).second.SetCreationTime(0);
    
  •        for (uint8 i = 0; i < MAX_REPORT_TYPES; i++)
    
  •        {
    
  •            (*it).second.SetTempReports(0,i);
    
  •            (*it).second.SetTempReportsTimer(0,i);
    
  •            (*it).second.SetTypeReports(i,0);
    
  •        }
    
  •    }
    
  •    CharacterDatabase.PExecute("DELETE FROM players_reports_status;");
    
  • }
  • else
  • {
  •    m_Players[guid].SetTotalReports(0);
    
  •    m_Players[guid].SetAverage(0);
    
  •    m_Players[guid].SetCreationTime(0);
    
  •    for (uint8 i = 0; i < MAX_REPORT_TYPES; i++)
    
  •    {
    
  •        m_Players[guid].SetTempReports(0,i);
    
  •        m_Players[guid].SetTempReportsTimer(0,i);
    
  •        m_Players[guid].SetTypeReports(i,0);
    
  •    }
    
  •    CharacterDatabase.PExecute("DELETE FROM players_reports_status WHERE guid=%u;",guid);
    
  • }
    +}

+void AnticheatMgr::ResetDailyReportStates()
+{

  • for (AnticheatPlayersDataMap::iterator it = m_Players.begin(); it != m_Players.end(); ++it)
    
  •     m_Players[(*it).first].SetDailyReportState(false);
    

+}
diff --git a/src/server/game/Anticheat/AnticheatMgr.h b/src/server/game/Anticheat/AnticheatMgr.h
new file mode 100644
index 0000000…554bdfa
— /dev/null
+++ b/src/server/game/Anticheat/AnticheatMgr.h
@@ -0,0 +1,103 @@
+/*

    • This program is free software; you can redistribute it and/or modify it
    • under the terms of the GNU General Public License as published by the
    • Free Software Foundation; either version 2 of the License, or (at your
    • option) any later version.
    • This program is distributed in the hope that it will be useful, but WITHOUT
    • ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    • FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
    • more details.
    • You should have received a copy of the GNU General Public License along
  • */

+#ifndef SC_ACMGR_H
+#define SC_ACMGR_H
+
+//#include <ace/Singleton.h>
+#include “Common.h”
+#include “SharedDefines.h”
+#include “ScriptPCH.h”
+#include “AnticheatData.h”
+#include “Chat.h”
+
+class Player;
+class AnticheatData;
+
+enum ReportTypes
+{

  • SPEED_HACK_REPORT = 0,
  • FLY_HACK_REPORT,
  • WALK_WATER_HACK_REPORT,
  • JUMP_HACK_REPORT,
  • TELEPORT_PLANE_HACK_REPORT,
  • CLIMB_HACK_REPORT,
  • // MAX_REPORT_TYPES
    +};

+enum DetectionTypes
+{

  • SPEED_HACK_DETECTION = 1,
  • FLY_HACK_DETECTION = 2,
  • WALK_WATER_HACK_DETECTION = 4,
  • JUMP_HACK_DETECTION = 8,
  • TELEPORT_PLANE_HACK_DETECTION = 16,
  • CLIMB_HACK_DETECTION = 32
    +};

+// GUIDLow is the key.
+typedef std::map<uint32, AnticheatData> AnticheatPlayersDataMap;
+
+class AnticheatMgr
+{
+// friend class ACE_Singleton<AnticheatMgr, ACE_Null_Mutex>;

  • AnticheatMgr();
  • ~AnticheatMgr();
  • public:
  • static AnticheatMgr* instance()
  •    {
    
  •       static AnticheatMgr* instance = new AnticheatMgr();
    
  •       return instance;
    
  •    }
    
  •    void StartHackDetection(Player* player, MovementInfo movementInfo, uint32 opcode);
    
  •    void DeletePlayerReport(Player* player, bool login);
    
  •    void DeletePlayerData(Player* player);
    
  •    void CreatePlayerData(Player* player);
    
  •    void SavePlayerData(Player* player);
    
  •    void StartScripts();
    
  •    void HandlePlayerLogin(Player* player);
    
  •    void HandlePlayerLogout(Player* player);
    
  •    uint32 GetTotalReports(uint32 lowGUID);
    
  •    float GetAverage(uint32 lowGUID);
    
  •    uint32 GetTypeReports(uint32 lowGUID, uint8 type);
    
  •    void AnticheatGlobalCommand(ChatHandler* handler);
    
  •    void AnticheatDeleteCommand(uint32 guid);
    
  •    void ResetDailyReportStates();
    
  • private:
  •    void SpeedHackDetection(Player* player, MovementInfo movementInfo);
    
  •    void FlyHackDetection(Player* player, MovementInfo movementInfo);
    
  •    void WalkOnWaterHackDetection(Player* player, MovementInfo movementInfo);
    
  •    void JumpHackDetection(Player* player, MovementInfo movementInfo,uint32 opcode);
    
  •    void TeleportPlaneHackDetection(Player* player, MovementInfo);
    
  •    void ClimbHackDetection(Player* player,MovementInfo movementInfo,uint32 opcode);
    
  •    void BuildReport(Player* player,uint8 reportType);
    
  •    bool MustCheckTempReports(uint8 type);
    
  •    AnticheatPlayersDataMap m_Players;                        ///< Player data
    

+};
+
+#define sAnticheatMgr AnticheatMgr::instance()
+
+#endif
diff --git a/src/server/game/Anticheat/AnticheatScripts.cpp b/src/server/game/Anticheat/AnticheatScripts.cpp
new file mode 100644
index 0000000…340178d
— /dev/null
+++ b/src/server/game/Anticheat/AnticheatScripts.cpp
@@ -0,0 +1,14 @@
+/*

    • This program is free software; you can redistribute it and/or modify it
    • under the terms of the GNU General Public License as published by the
    • Free Software Foundation; either version 2 of the License, or (at your
    • option) any later version.
    • This program is distributed in the hope that it will be useful, but WITHOUT
    • ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    • FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
    • more details.
    • You should have received a copy of the GNU General Public License along
  • */

+#include “AnticheatScripts.h”
+#include “AnticheatMgr.h”
+
+AnticheatScripts::AnticheatScripts(): PlayerScript(“AnticheatScripts”) {}
+
+void AnticheatScripts::OnLogout(Player* player)
+{

  • sAnticheatMgr->HandlePlayerLogout(player);
    +}

+void AnticheatScripts::OnLogin(Player* player,bool)
+{

  • sAnticheatMgr->HandlePlayerLogin(player);
    +}
    diff --git a/src/server/game/Anticheat/AnticheatScripts.h b/src/server/game/Anticheat/AnticheatScripts.h
    new file mode 100644
    index 0000000…25d34d0
    — /dev/null
    +++ b/src/server/game/Anticheat/AnticheatScripts.h
    @@ -0,0 +1,15 @@
    +/*
    • This program is free software; you can redistribute it and/or modify it
    • under the terms of the GNU General Public License as published by the
    • Free Software Foundation; either version 2 of the License, or (at your
    • option) any later version.
    • This program is distributed in the hope that it will be useful, but WITHOUT
    • ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    • FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
    • more details.
    • You should have received a copy of the GNU General Public License along
  • */

+#ifndef SC_ACSCRIPTS_H
+#define SC_ACSCRIPTS_H
+
+#include “ScriptPCH.h”
+
+class AnticheatScripts: public PlayerScript
+{

  • public:
  •    AnticheatScripts();
    
  •    void OnLogout(Player* player);
    
  •    void OnLogin(Player* player,bool);
    

+};
+
+#endif
\ No newline at end of file
diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
index d748be4…259390b 100644
— a/src/server/game/CMakeLists.txt
+++ b/src/server/game/CMakeLists.txt
@@ -9,6 +9,7 @@

implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

file(GLOB_RECURSE sources_Accounts Accounts/.cpp Accounts/.h)
+file(GLOB_RECURSE sources_Anticheat Anticheat/.cpp Anticheat/.h)
file(GLOB_RECURSE sources_Achievements Achievements/.cpp Achievements/.h)
file(GLOB_RECURSE sources_Addons Addons/.cpp Addons/.h)
file(GLOB_RECURSE sources_AI AI/.cpp AI/.h)
@@ -60,6 +61,7 @@ endif ()
set(game_STAT_SRCS
${game_STAT_SRCS}
${sources_Accounts}

  • ${sources_Anticheat}
    ${sources_Achievements}
    ${sources_Addons}
    ${sources_AI}
    @@ -131,6 +133,7 @@ include_directories(
    ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/Accounts

  • ${CMAKE_CURRENT_SOURCE_DIR}/Anticheat
    ${CMAKE_CURRENT_SOURCE_DIR}/Achievements
    ${CMAKE_CURRENT_SOURCE_DIR}/Addons
    ${CMAKE_CURRENT_SOURCE_DIR}/AI
    diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
    index ea85f8b…7842600 100644
    — a/src/server/game/Entities/Player/Player.cpp
    +++ b/src/server/game/Entities/Player/Player.cpp
    @@ -19,6 +19,7 @@
    #include “Player.h”
    #include “AccountMgr.h”
    #include “AchievementMgr.h”
    +#include “AnticheatMgr.h”
    #include “ArenaTeam.h”
    #include “ArenaTeamMgr.h”
    #include “Battlefield.h”
    @@ -19589,6 +19590,12 @@ void Player::SaveToDB(bool create /=false/)

    CharacterDatabase.CommitTransaction(trans);

  • // we save the data here to prevent spamming

  • sAnticheatMgr->SavePlayerData(this);

  • // in this way we prevent to spam the db by each report made!

  • // sAnticheatMgr->SavePlayerData(this);

  • // save pet (hunter pet level and experience and all type pets health/mana).
    if (Pet* pet = GetPet())
    pet->SavePetToDB(PET_SAVE_AS_CURRENT);
    diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
    index beac32b…3ebf351 100644
    — a/src/server/game/Entities/Unit/Unit.cpp
    +++ b/src/server/game/Entities/Unit/Unit.cpp
    @@ -16,6 +16,7 @@

+#include “AnticheatMgr.h”
#include “Unit.h”
#include “Common.h”
#include “Battlefield.h”
@@ -12195,6 +12196,9 @@ void Unit::SetVisible(bool x)

void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
{

  • //if (this->ToPlayer())
  • // sAnticheatMgr->DisableAnticheatDetection(this->ToPlayer());
  • int32 main_speed_mod = 0;
    float stack_bonus = 1.0f;
    float non_stack_bonus = 1.0f;
    diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
    index 68d8931…e4d18d5 100644
    — a/src/server/game/Handlers/MovementHandler.cpp
    +++ b/src/server/game/Handlers/MovementHandler.cpp
    @@ -16,6 +16,7 @@

+#include “AnticheatMgr.h”
#include “Common.h”
#include “WorldPacket.h”
#include “WorldSession.h”
@@ -341,6 +342,9 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ()));
}

  • if (plrMover)
  •    sAnticheatMgr->StartHackDetection(plrMover, movementInfo, opcode);
    
  • uint32 mstime = getMSTime();
    /----------------------/
    if (m_clientTimeDelay == 0)
    diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
    index bd43fbe…df86789 100644
    — a/src/server/game/Scripting/ScriptLoader.cpp
    +++ b/src/server/game/Scripting/ScriptLoader.cpp
    @@ -17,6 +17,7 @@

#include “ScriptLoader.h”
#include “World.h”
+#include “AnticheatMgr.h”

// spells
void AddSC_deathknight_spell_scripts();
@@ -40,6 +41,7 @@ void AddSC_SmartScripts();
void AddSC_account_commandscript();
void AddSC_achievement_commandscript();
void AddSC_ahbot_commandscript();
+void AddSC_anticheat_commandscript();
void AddSC_arena_commandscript();
void AddSC_ban_commandscript();
void AddSC_bf_commandscript();
@@ -695,6 +697,7 @@ void AddScripts()
AddSpellScripts();
AddSC_SmartScripts();
AddCommandScripts();

  • sAnticheatMgr->StartScripts();
    #ifdef SCRIPTS
    AddWorldScripts();
    AddEasternKingdomsScripts();
    @@ -729,6 +732,7 @@ void AddSpellScripts()

void AddCommandScripts()
{

  • AddSC_anticheat_commandscript();
    AddSC_account_commandscript();
    AddSC_achievement_commandscript();
    AddSC_ahbot_commandscript();
    diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
    index 2b5b65f…ea668e0 100644
    — a/src/server/game/Spells/SpellEffects.cpp
    +++ b/src/server/game/Spells/SpellEffects.cpp
    @@ -16,6 +16,7 @@

+#include “AnticheatMgr.h”
#include “Common.h”
#include “DatabaseEnv.h”
#include “WorldPacket.h”
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index afd87b8…97dc07c 100644
— a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -27,6 +27,7 @@
#include “AuctionHouseMgr.h”
#include “BattlefieldMgr.h”
#include “BattlegroundMgr.h”
+#include “AnticheatMgr.h”
#include “CalendarMgr.h”
#include “Channel.h”
#include “CharacterDatabaseCleaner.h”
@@ -1253,6 +1254,11 @@ void World::LoadConfigSettings(bool reload)
m_bool_configs[CONFIG_PDUMP_NO_OVERWRITE] = sConfigMgr->GetBoolDefault(“PlayerDump.DisallowOverwrite”, true);
m_bool_configs[CONFIG_UI_QUESTLEVELS_IN_DIALOGS] = sConfigMgr->GetBoolDefault(“UI.ShowQuestLevelsInDialogs”, false);

  • m_bool_configs[CONFIG_ANTICHEAT_ENABLE] = sConfigMgr->GetBoolDefault(“Anticheat.Enable”, true);

  • m_int_configs[CONFIG_ANTICHEAT_REPORTS_INGAME_NOTIFICATION] = sConfigMgr->GetIntDefault(“Anticheat.ReportsForIngameWarnings”, 70);

  • m_int_configs[CONFIG_ANTICHEAT_DETECTIONS_ENABLED] = sConfigMgr->GetIntDefault(“Anticheat.DetectionsEnabled”,31);

  • m_int_configs[CONFIG_ANTICHEAT_MAX_REPORTS_FOR_DAILY_REPORT] = sConfigMgr->GetIntDefault(“Anticheat.MaxReportsForDailyReport”,70);

  • // Wintergrasp battlefield
    m_bool_configs[CONFIG_WINTERGRASP_ENABLE] = sConfigMgr->GetBoolDefault(“Wintergrasp.Enable”, false);
    m_int_configs[CONFIG_WINTERGRASP_PLR_MAX] = sConfigMgr->GetIntDefault(“Wintergrasp.PlayerMax”, 100);
    @@ -2940,6 +2946,8 @@ void World::ResetDailyQuests()

    // change available dailies
    sPoolMgr->ChangeDailyQuests();

  • sAnticheatMgr->ResetDailyReportStates();
    }

void World::LoadDBAllowedSecurityLevel()
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 2f13051…0645be5 100644
— a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -145,6 +145,7 @@ enum WorldBoolConfigs
CONFIG_ALLOW_TICKETS,
CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES,
CONFIG_PRESERVE_CUSTOM_CHANNELS,

  • CONFIG_ANTICHEAT_ENABLE,
    CONFIG_PDUMP_NO_PATHS,
    CONFIG_PDUMP_NO_OVERWRITE,
    CONFIG_QUEST_IGNORE_AUTO_ACCEPT,
    @@ -383,7 +384,10 @@ enum WorldIntConfigs
    CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION,
    CONFIG_PERSISTENT_CHARACTER_CLEAN_FLAGS,
    CONFIG_LFG_OPTIONSMASK,
  • CONFIG_ANTICHEAT_REPORTS_INGAME_NOTIFICATION,
  • CONFIG_ANTICHEAT_MAX_REPORTS_FOR_DAILY_REPORT,
    CONFIG_MAX_INSTANCES_PER_HOUR,
  • CONFIG_ANTICHEAT_DETECTIONS_ENABLED,
    CONFIG_WARDEN_CLIENT_RESPONSE_DELAY,
    CONFIG_WARDEN_CLIENT_CHECK_HOLDOFF,
    CONFIG_WARDEN_CLIENT_FAIL_ACTION,
    diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
    index f11791e…522ece8 100644
    — a/src/server/scripts/CMakeLists.txt
    +++ b/src/server/scripts/CMakeLists.txt
    @@ -69,6 +69,7 @@ include_directories(
    ${CMAKE_SOURCE_DIR}/src/server/shared
    ${CMAKE_SOURCE_DIR}/src/server/shared/Database
    ${CMAKE_SOURCE_DIR}/src/server/game/Accounts
  • ${CMAKE_SOURCE_DIR}/src/server/game/Anticheat
    ${CMAKE_SOURCE_DIR}/src/server/game/Achievements
    ${CMAKE_SOURCE_DIR}/src/server/game/Addons
    ${CMAKE_SOURCE_DIR}/src/server/game/AI
    diff --git a/src/server/scripts/Commands/cs_anticheat.cpp b/src/server/scripts/Commands/cs_anticheat.cpp
    new file mode 100644
    index 0000000…3cc6784
    — /dev/null
    +++ b/src/server/scripts/Commands/cs_anticheat.cpp
    @@ -0,0 +1,262 @@
    +/*
    • This program is free software; you can redistribute it and/or modify it
    • under the terms of the GNU General Public License as published by the
    • Free Software Foundation; either version 2 of the License, or (at your
    • option) any later version.
    • This program is distributed in the hope that it will be useful, but WITHOUT
    • ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    • FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
    • more details.
    • You should have received a copy of the GNU General Public License along
  • */

+#include “Language.h”
+#include “ScriptMgr.h”
+#include “ObjectMgr.h”
+#include “Chat.h”
+#include “AnticheatMgr.h”
+
+class anticheat_commandscript : public CommandScript
+{
+public:

  • anticheat_commandscript() : CommandScript(“anticheat_commandscript”) { }
  • ChatCommand* GetCommands() const
  • {
  •    static ChatCommand anticheatCommandTable[] =
    
  •    {
    
  •        { "geral",         SEC_GAMEMASTER,     true,  &HandleAntiCheatGlobalCommand,         "", NULL },
    
  •        { "info",         SEC_GAMEMASTER,     true,  &HandleAntiCheatPlayerCommand,         "", NULL },
    
  •        { "deletar",         SEC_ADMINISTRATOR,  true,  &HandleAntiCheatDeleteCommand,         "", NULL },
    
  •        { "ativar",         SEC_ADMINISTRATOR,  true,  &HandleAntiCheatHandleCommand,         "", NULL },
    
  •        { "prender",         SEC_GAMEMASTER,     true,  &HandleAnticheatJailCommand,         "", NULL },
    
  •        { "aviso",           SEC_GAMEMASTER,     true,  &HandleAnticheatWarnCommand,         "", NULL },
    
  •        { NULL,             0,                     false, NULL,                                           "", NULL }
    
  •    };
    
  •    static ChatCommand commandTable[] =
    
  •    {
    
  •        { "antihacker",      SEC_GAMEMASTER,     true, NULL,                     "",  anticheatCommandTable},
    
  •        { NULL,             0,                  false, NULL,                               "", NULL }
    
  •    };
    
  •    return commandTable;
    
  • }
  • static bool HandleAnticheatWarnCommand(ChatHandler* handler, const char* args)
  • {
  •    if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
    
  •        return false;
    
  •    Player* pTarget = NULL;
    
  •    std::string strCommand;
    
  •    char* command = strtok((char*)args, " ");
    
  •    if (command)
    
  •    {
    
  •        strCommand = command;
    
  •        normalizePlayerName(strCommand);
    
  •        pTarget = sObjectAccessor->FindPlayerByName(strCommand.c_str()); //get player by name
    
  •    }else
    
  •        pTarget = handler->getSelectedPlayer();
    
  •    if (!pTarget)
    
  •        return false;
    
  •    WorldPacket data;
    
  •    // need copy to prevent corruption by strtok call in LineFromMessage original string
    
  •    char* buf = strdup("O Sistema Anti Hacker informou várias vezes que você pode esta usando algum tipo de Hacker. Você será monitorado a partir de agora!");
    
  •    char* pos = buf;
    
  •    while (char* line = handler->LineFromMessage(pos))
    
  •    {
    
  •        handler->BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line);
    
  •        pTarget->GetSession()->SendPacket(&data);
    
  •    }
    
  •    free(buf);
    
  •    return true;
    
  • }
  • static bool HandleAnticheatJailCommand(ChatHandler* handler, const char* args)
  • {
  •    if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
    
  •        return false;
    
  •    Player* pTarget = NULL;
    
  •    std::string strCommand;
    
  •    char* command = strtok((char*)args, " ");
    
  •    if (command)
    
  •    {
    
  •        strCommand = command;
    
  •        normalizePlayerName(strCommand);
    
  •        pTarget = sObjectAccessor->FindPlayerByName(strCommand.c_str()); //get player by name
    
  •    }else
    
  •        pTarget = handler->getSelectedPlayer();
    
  •    if (!pTarget)
    
  •    {
    
  •        handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
    
  •        handler->SetSentErrorMessage(true);
    
  •        return false;
    
  •    }
    
  •    if (pTarget == handler->GetSession()->GetPlayer())
    
  •        return false;
    
  •    // teleport both to jail.
    
  •    pTarget->TeleportTo(1,16226.5f,16403.6f,-64.5f,3.2f);
    
  •    handler->GetSession()->GetPlayer()->TeleportTo(1,16226.5f,16403.6f,-64.5f,3.2f);
    
  •    WorldLocation loc;
    
  •    // the player should be already there, but no :(
    
  •    // pTarget->GetPosition(&loc);
    
  •    loc.m_mapId = 1;
    
  •    loc.m_positionX = 16226.5f;
    
  •    loc.m_positionY = 16403.6f;
    
  •    loc.m_positionZ = -64.5f;
    
  •    loc.m_orientation = 3.2f;
    
  •    pTarget->SetHomebind(loc,876);
    
  •    return true;
    
  • }
  • static bool HandleAntiCheatDeleteCommand(ChatHandler* handler, const char* args)
  • {
  •    if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
    
  •        return false;
    
  •    std::string strCommand;
    
  •    char* command = strtok((char*)args, " "); //get entered name
    
  •    if (!command)
    
  •        return true;
    
  •    strCommand = command;
    
  •    if (strCommand.compare("deleteall") == 0)
    
  •        sAnticheatMgr->AnticheatDeleteCommand(0);
    
  •    else
    
  •    {
    
  •        normalizePlayerName(strCommand);
    
  •        Player* player = sObjectAccessor->FindPlayerByName(strCommand.c_str()); //get player by name
    
  •        if (!player)
    
  •            handler->PSendSysMessage("Jogador não existe!");
    
  •        else
    
  •            sAnticheatMgr->AnticheatDeleteCommand(player->GetGUIDLow());
    
  •    }
    
  •    return true;
    
  • }
  • static bool HandleAntiCheatPlayerCommand(ChatHandler* handler, const char* args)
  • {
  •    if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
    
  •        return false;
    
  •    std::string strCommand;
    
  •    char* command = strtok((char*)args, " ");
    
  •    uint32 guid = 0;
    
  •    Player* player = NULL;
    
  •    if (command)
    
  •    {
    
  •        strCommand = command;
    
  •        normalizePlayerName(strCommand);
    
  •        player = sObjectAccessor->FindPlayerByName(strCommand.c_str()); //get player by name
    
  •        if (player)
    
  •            guid = player->GetGUIDLow();
    
  •    }else
    
  •    {
    
  •        player = handler->getSelectedPlayer();
    
  •        if (player)
    
  •            guid = player->GetGUIDLow();
    
  •    }
    
  •    if (!guid)
    
  •    {
    
  •        handler->PSendSysMessage("Não há nenhum jogador!");
    
  •        return true;
    
  •    }
    
  •    float average = sAnticheatMgr->GetAverage(guid);
    
  •    uint32 total_reports = sAnticheatMgr->GetTotalReports(guid);
    
  •    uint32 speed_reports = sAnticheatMgr->GetTypeReports(guid,0);
    
  •    uint32 fly_reports = sAnticheatMgr->GetTypeReports(guid,1);
    
  •    uint32 jump_reports = sAnticheatMgr->GetTypeReports(guid,3);
    
  •    uint32 waterwalk_reports = sAnticheatMgr->GetTypeReports(guid,2);
    
  •    uint32 teleportplane_reports = sAnticheatMgr->GetTypeReports(guid,4);
    
  •    uint32 climb_reports = sAnticheatMgr->GetTypeReports(guid,5);
    
  •    handler->PSendSysMessage("Informações sobre o Jogador %s",player->GetName().c_str());
    
  •    handler->PSendSysMessage("Média: %f || Total de Reports: %u ",average,total_reports);
    
  •    handler->PSendSysMessage("Speed Hacker: %u || Fly Hacker: %u || Jump Hacker: %u ",speed_reports,fly_reports,jump_reports);
    
  •    handler->PSendSysMessage("Walk On Water Hacker: %u  || Teleport To Plane Hacker: %u",waterwalk_reports,teleportplane_reports);
    
  •    handler->PSendSysMessage("Climb Hacker: %u", climb_reports);
    
  •    return true;
    
  • }
  • static bool HandleAntiCheatHandleCommand(ChatHandler* handler, const char* args)
  • {
  •    std::string strCommand;
    
  •    char* command = strtok((char*)args, " ");
    
  •    if (!command)
    
  •        return true;
    
  •    if (!handler->GetSession()->GetPlayer())
    
  •        return true;
    
  •    strCommand = command;
    
  •    if (strCommand.compare("on") == 0)
    
  •    {
    
  •        sWorld->setBoolConfig(CONFIG_ANTICHEAT_ENABLE,true);
    
  •        handler->SendSysMessage("O Sistema Anti Hacker esta: Ativado!");
    
  •    }
    
  •    else if (strCommand.compare("off") == 0)
    
  •    {
    
  •        sWorld->setBoolConfig(CONFIG_ANTICHEAT_ENABLE,false);
    
  •        handler->SendSysMessage("O Sistema Anti Hacker esta: Desativado!");
    
  •    }
    
  •    return true;
    
  • }
  • static bool HandleAntiCheatGlobalCommand(ChatHandler* handler, const char* /* args */)
  • {
  •    if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
    
  •    {
    
  •        handler->PSendSysMessage("O Sistema Anti Hacker esta desativado!");
    
  •        return true;
    
  •    }
    
  •    sAnticheatMgr->AnticheatGlobalCommand(handler);
    
  •    return true;
    
  • }
    +};

+void AddSC_anticheat_commandscript()
+{

  • new anticheat_commandscript();
    +}
    diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
    index c40da51…48ee00b 100644
    — a/src/server/worldserver/worldserver.conf.dist
    +++ b/src/server/worldserver/worldserver.conf.dist
    @@ -2661,6 +2661,40 @@ LevelReq.Auction = 1
    LevelReq.Mail = 1

+# Anticheat.Enable
+# Description: Enables or disables the Anticheat System functionality
+# Default: 1 - (Enabled)
+# 0 - (Disabled)
+
+Anticheat.Enable = 1
+
+# Anticheat.ReportsForIngameWarnings
+# Description: How many reports the player must have to notify to GameMasters ingame when he generates a new report.
+# Default: 70
+
+Anticheat.ReportsForIngameWarnings = 70
+
+# Anticheat.DetectionsEnabled
+# Description: It represents which detections are enabled.
+#
+# SPEED_HACK_DETECTION = 1
+# FLY_HACK_DETECTION = 2
+# WALK_WATER_HACK_DETECTION = 4
+# JUMP_HACK_DETECTION = 8
+# TELEPORT_PLANE_HACK_DETECTION = 16
+# CLIMB_HACK_DETECTION = 32
+#
+# Default: 31
+
+Anticheat.DetectionsEnabled = 31
+
+# Anticheat.MaxReportsForDailyReport
+# Description: How many reports must the player have to make a report that it is in DB for a day (not only during the player’s session).
+# Default: 70
+
+Anticheat.MaxReportsForDailyReport = 70
+
+#

PlayerDump.DisallowPaths

Description: Disallow using paths in PlayerDump output files

Default: 1


2.1.3

[CENTER]http://i.imgur.com/l2EPotH.png[/CENTER]

[ATTACH]1320._xfImport[/ATTACH]

[ATTACH]1321._xfImport[/ATTACH]

Valeu Nofferar por compartilha com a gente