refactor(Core/Battlefield): replace manual timers with TaskScheduler … (#25083)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3627,6 +3627,15 @@ Wintergrasp.NoBattleTimer = 150
|
|||||||
|
|
||||||
Wintergrasp.CrashRestartTimer = 10
|
Wintergrasp.CrashRestartTimer = 10
|
||||||
|
|
||||||
|
#
|
||||||
|
# Wintergrasp.SkipBattleSessionCount
|
||||||
|
# Description: When the peace timer expires, if the number of active sessions
|
||||||
|
# exceeds this value, a new war will not start.
|
||||||
|
# Set to 0 to disable this check.
|
||||||
|
# Default: 3500
|
||||||
|
|
||||||
|
Wintergrasp.SkipBattleSessionCount = 3500
|
||||||
|
|
||||||
#
|
#
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "ObjectAccessor.h"
|
#include "ObjectAccessor.h"
|
||||||
#include "ObjectMgr.h"
|
#include "ObjectMgr.h"
|
||||||
#include "Transport.h"
|
#include "Transport.h"
|
||||||
|
#include "World.h"
|
||||||
#include "WorldPacket.h"
|
#include "WorldPacket.h"
|
||||||
#include "WorldSessionMgr.h"
|
#include "WorldSessionMgr.h"
|
||||||
|
|
||||||
@@ -57,9 +58,6 @@ Battlefield::Battlefield() :
|
|||||||
NoWarBattleTime(0),
|
NoWarBattleTime(0),
|
||||||
RestartAfterCrash(0),
|
RestartAfterCrash(0),
|
||||||
TimeForAcceptInvite(20),
|
TimeForAcceptInvite(20),
|
||||||
KickDontAcceptTimer(1000),
|
|
||||||
KickAfkPlayersTimer(1000),
|
|
||||||
LastResurrectTimer(RESURRECTION_INTERVAL),
|
|
||||||
StartGroupingTimer(0),
|
StartGroupingTimer(0),
|
||||||
StartGrouping(false)
|
StartGrouping(false)
|
||||||
{
|
{
|
||||||
@@ -147,7 +145,11 @@ bool Battlefield::Update(uint32 diff)
|
|||||||
{
|
{
|
||||||
if (Timer <= diff)
|
if (Timer <= diff)
|
||||||
{
|
{
|
||||||
if (!IsEnabled() || (!IsWarTime() && sWorldSessionMgr->GetActiveSessionCount() > 3500)) // if WG is disabled or there is more than 3500 connections, switch automatically
|
uint32 sessionLimit = sWorld->getIntConfig(CONFIG_WINTERGRASP_SKIP_BATTLE_SESSION_COUNT);
|
||||||
|
bool tooManySessions = sessionLimit && !IsWarTime()
|
||||||
|
&& sWorldSessionMgr->GetActiveSessionCount() > sessionLimit;
|
||||||
|
|
||||||
|
if (!IsEnabled() || tooManySessions)
|
||||||
{
|
{
|
||||||
Active = true;
|
Active = true;
|
||||||
EndBattle(false);
|
EndBattle(false);
|
||||||
@@ -174,52 +176,16 @@ bool Battlefield::Update(uint32 diff)
|
|||||||
SendUpdateWorldStates();
|
SendUpdateWorldStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_scheduler.Update(diff);
|
||||||
|
|
||||||
bool objectiveChanged = false;
|
bool objectiveChanged = false;
|
||||||
if (IsWarTime())
|
if (IsWarTime())
|
||||||
{
|
{
|
||||||
if (KickAfkPlayersTimer <= diff)
|
|
||||||
{
|
|
||||||
KickAfkPlayersTimer = 20000;
|
|
||||||
KickAfkPlayers();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
KickAfkPlayersTimer -= diff;
|
|
||||||
|
|
||||||
// Kick players who chose not to accept invitation to the battle
|
|
||||||
if (KickDontAcceptTimer <= diff)
|
|
||||||
{
|
|
||||||
time_t now = GameTime::GetGameTime().count();
|
|
||||||
for (uint8 team = 0; team < PVP_TEAMS_COUNT; ++team)
|
|
||||||
for (PlayerTimerMap::value_type const& pair : InvitedPlayers[team])
|
|
||||||
if (pair.second <= now)
|
|
||||||
KickPlayerFromBattlefield(pair.first);
|
|
||||||
|
|
||||||
InvitePlayersInZoneToWar();
|
|
||||||
for (uint8 team = 0; team < PVP_TEAMS_COUNT; ++team)
|
|
||||||
for (PlayerTimerMap::value_type const& pair : PlayersWillBeKick[team])
|
|
||||||
if (pair.second <= now)
|
|
||||||
KickPlayerFromBattlefield(pair.first);
|
|
||||||
|
|
||||||
KickDontAcceptTimer = 5000;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
KickDontAcceptTimer -= diff;
|
|
||||||
|
|
||||||
for (BfCapturePoint* cp : CapturePoints)
|
for (BfCapturePoint* cp : CapturePoints)
|
||||||
if (cp->Update(diff))
|
if (cp->Update(diff))
|
||||||
objectiveChanged = true;
|
objectiveChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LastResurrectTimer <= diff)
|
|
||||||
{
|
|
||||||
for (BfGraveyard* gy : GraveyardList)
|
|
||||||
if (gy)
|
|
||||||
gy->Resurrect();
|
|
||||||
LastResurrectTimer = RESURRECTION_INTERVAL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LastResurrectTimer -= diff;
|
|
||||||
|
|
||||||
return objectiveChanged;
|
return objectiveChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,6 +308,30 @@ void Battlefield::StartBattle()
|
|||||||
Timer = BattleTime;
|
Timer = BattleTime;
|
||||||
Active = true;
|
Active = true;
|
||||||
|
|
||||||
|
// Schedule war-only periodic timers
|
||||||
|
_scheduler.Schedule(1s, BATTLEFIELD_TIMER_GROUP_WAR, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
KickAfkPlayers();
|
||||||
|
context.Repeat(20s);
|
||||||
|
});
|
||||||
|
|
||||||
|
_scheduler.Schedule(1s, BATTLEFIELD_TIMER_GROUP_WAR, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
time_t now = GameTime::GetGameTime().count();
|
||||||
|
for (uint8 team = 0; team < PVP_TEAMS_COUNT; ++team)
|
||||||
|
for (PlayerTimerMap::value_type const& pair : InvitedPlayers[team])
|
||||||
|
if (pair.second <= now)
|
||||||
|
KickPlayerFromBattlefield(pair.first);
|
||||||
|
|
||||||
|
InvitePlayersInZoneToWar();
|
||||||
|
for (uint8 team = 0; team < PVP_TEAMS_COUNT; ++team)
|
||||||
|
for (PlayerTimerMap::value_type const& pair : PlayersWillBeKick[team])
|
||||||
|
if (pair.second <= now)
|
||||||
|
KickPlayerFromBattlefield(pair.first);
|
||||||
|
|
||||||
|
context.Repeat(5s);
|
||||||
|
});
|
||||||
|
|
||||||
InvitePlayersInZoneToWar();
|
InvitePlayersInZoneToWar();
|
||||||
InvitePlayersInQueueToWar();
|
InvitePlayersInQueueToWar();
|
||||||
|
|
||||||
@@ -359,6 +349,8 @@ void Battlefield::EndBattle(bool endByTimer)
|
|||||||
|
|
||||||
Active = false;
|
Active = false;
|
||||||
|
|
||||||
|
_scheduler.CancelGroup(BATTLEFIELD_TIMER_GROUP_WAR);
|
||||||
|
|
||||||
StartGrouping = false;
|
StartGrouping = false;
|
||||||
|
|
||||||
if (!endByTimer)
|
if (!endByTimer)
|
||||||
@@ -626,7 +618,9 @@ void Battlefield::RemovePlayerFromResurrectQueue(ObjectGuid playerGuid)
|
|||||||
void Battlefield::SendAreaSpiritHealerQueryOpcode(Player* player, ObjectGuid const& guid)
|
void Battlefield::SendAreaSpiritHealerQueryOpcode(Player* player, ObjectGuid const& guid)
|
||||||
{
|
{
|
||||||
WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12);
|
WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12);
|
||||||
uint32 time = LastResurrectTimer; // resurrect every 30 seconds
|
Milliseconds remaining = _scheduler.GetNextGroupOccurrence(BATTLEFIELD_TIMER_GROUP_RESURRECT);
|
||||||
|
uint32 time = static_cast<uint32>(std::clamp(remaining,
|
||||||
|
Milliseconds::zero(), Milliseconds(RESURRECTION_INTERVAL)).count());
|
||||||
|
|
||||||
data << guid << time;
|
data << guid << time;
|
||||||
ASSERT(player);
|
ASSERT(player);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "GameObject.h"
|
#include "GameObject.h"
|
||||||
#include "ObjectAccessor.h"
|
#include "ObjectAccessor.h"
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
|
#include "TaskScheduler.h"
|
||||||
#include "ZoneScript.h"
|
#include "ZoneScript.h"
|
||||||
|
|
||||||
enum BattlefieldTypes
|
enum BattlefieldTypes
|
||||||
@@ -55,6 +56,13 @@ enum BattlefieldSounds
|
|||||||
|
|
||||||
constexpr auto BATTLEFIELD_OBJECTIVE_UPDATE_INTERVAL = 1000;
|
constexpr auto BATTLEFIELD_OBJECTIVE_UPDATE_INTERVAL = 1000;
|
||||||
|
|
||||||
|
enum BattlefieldTimerGroups
|
||||||
|
{
|
||||||
|
BATTLEFIELD_TIMER_GROUP_RESURRECT = 1,
|
||||||
|
BATTLEFIELD_TIMER_GROUP_WAR = 2,
|
||||||
|
BATTLEFIELD_TIMER_GROUP_SAVE = 3,
|
||||||
|
};
|
||||||
|
|
||||||
const uint32 BattlefieldFactions[PVP_TEAMS_COUNT] =
|
const uint32 BattlefieldFactions[PVP_TEAMS_COUNT] =
|
||||||
{
|
{
|
||||||
1732, // Alliance
|
1732, // Alliance
|
||||||
@@ -401,18 +409,16 @@ protected:
|
|||||||
uint32 NoWarBattleTime; // Time between two battles
|
uint32 NoWarBattleTime; // Time between two battles
|
||||||
uint32 RestartAfterCrash; // Delay to restart Wintergrasp if the server crashed during a running battle
|
uint32 RestartAfterCrash; // Delay to restart Wintergrasp if the server crashed during a running battle
|
||||||
uint32 TimeForAcceptInvite;
|
uint32 TimeForAcceptInvite;
|
||||||
uint32 KickDontAcceptTimer;
|
|
||||||
WorldLocation KickPosition; // Position where players are teleported if they switch to afk during the battle or if they don't accept invitation
|
WorldLocation KickPosition; // Position where players are teleported if they switch to afk during the battle or if they don't accept invitation
|
||||||
|
|
||||||
uint32 KickAfkPlayersTimer; // Timer for check Afk in war
|
|
||||||
|
|
||||||
// Graveyard variables
|
// Graveyard variables
|
||||||
GraveyardVect GraveyardList; // Vector which contains the different GY of the battle
|
GraveyardVect GraveyardList; // Vector which contains the different GY of the battle
|
||||||
uint32 LastResurrectTimer; // Timer for resurrect player every 30 sec
|
|
||||||
|
|
||||||
uint32 StartGroupingTimer; // Timer for invite players in area 15 minutes before start battle
|
uint32 StartGroupingTimer; // Timer for invite players in area 15 minutes before start battle
|
||||||
bool StartGrouping; // bool for knowing if all players in area have been invited
|
bool StartGrouping; // bool for knowing if all players in area have been invited
|
||||||
|
|
||||||
|
TaskScheduler _scheduler;
|
||||||
|
|
||||||
GuidUnorderedSet Groups[PVP_TEAMS_COUNT]; // Contains different raid groups
|
GuidUnorderedSet Groups[PVP_TEAMS_COUNT]; // Contains different raid groups
|
||||||
|
|
||||||
std::vector<uint64> Data64;
|
std::vector<uint64> Data64;
|
||||||
|
|||||||
@@ -77,8 +77,6 @@ bool BattlefieldWG::SetupBattlefield()
|
|||||||
|
|
||||||
Data32.resize(BATTLEFIELD_WG_DATA_MAX);
|
Data32.resize(BATTLEFIELD_WG_DATA_MAX);
|
||||||
|
|
||||||
SaveTimer = 60000;
|
|
||||||
|
|
||||||
// Init Graveyards
|
// Init Graveyards
|
||||||
SetGraveyardNumber(BATTLEFIELD_WG_GRAVEYARD_MAX);
|
SetGraveyardNumber(BATTLEFIELD_WG_GRAVEYARD_MAX);
|
||||||
|
|
||||||
@@ -189,37 +187,31 @@ bool BattlefieldWG::SetupBattlefield()
|
|||||||
}
|
}
|
||||||
|
|
||||||
UpdateCounterVehicle(true);
|
UpdateCounterVehicle(true);
|
||||||
|
|
||||||
|
// Schedule always-running periodic timers
|
||||||
|
_scheduler.Schedule(Milliseconds(RESURRECTION_INTERVAL),
|
||||||
|
BATTLEFIELD_TIMER_GROUP_RESURRECT, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
for (BfGraveyard* gy : GraveyardList)
|
||||||
|
if (gy)
|
||||||
|
gy->Resurrect();
|
||||||
|
context.Repeat();
|
||||||
|
});
|
||||||
|
|
||||||
|
_scheduler.Schedule(60s, BATTLEFIELD_TIMER_GROUP_SAVE, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
sWorldState->setWorldState(WORLD_STATE_BATTLEFIELD_WG_ACTIVE, Active);
|
||||||
|
sWorldState->setWorldState(WORLD_STATE_BATTLEFIELD_WG_DEFENDER, DefenderTeam);
|
||||||
|
sWorldState->setWorldState(ClockWorldState[0], Timer);
|
||||||
|
context.Repeat();
|
||||||
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BattlefieldWG::Update(uint32 diff)
|
bool BattlefieldWG::Update(uint32 diff)
|
||||||
{
|
{
|
||||||
bool result = Battlefield::Update(diff);
|
return Battlefield::Update(diff);
|
||||||
if (SaveTimer <= diff)
|
|
||||||
{
|
|
||||||
sWorldState->setWorldState(WORLD_STATE_BATTLEFIELD_WG_ACTIVE, Active);
|
|
||||||
sWorldState->setWorldState(WORLD_STATE_BATTLEFIELD_WG_DEFENDER, DefenderTeam);
|
|
||||||
sWorldState->setWorldState(ClockWorldState[0], Timer);
|
|
||||||
SaveTimer = 60 * IN_MILLISECONDS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
SaveTimer -= diff;
|
|
||||||
|
|
||||||
// Update Tenacity
|
|
||||||
if (IsWarTime())
|
|
||||||
{
|
|
||||||
if (TenacityUpdateTimer <= diff)
|
|
||||||
{
|
|
||||||
TenacityUpdateTimer = 10000;
|
|
||||||
if (!UpdateTenacityList.empty())
|
|
||||||
UpdateTenacity();
|
|
||||||
UpdateTenacityList.clear();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
TenacityUpdateTimer -= diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattlefieldWG::OnBattleStart()
|
void BattlefieldWG::OnBattleStart()
|
||||||
@@ -293,7 +285,14 @@ void BattlefieldWG::OnBattleStart()
|
|||||||
|
|
||||||
// Xinef: reset tenacity counter
|
// Xinef: reset tenacity counter
|
||||||
TenacityStack = 0;
|
TenacityStack = 0;
|
||||||
TenacityUpdateTimer = 20000;
|
|
||||||
|
_scheduler.Schedule(20s, BATTLEFIELD_TIMER_GROUP_WAR, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (!UpdateTenacityList.empty())
|
||||||
|
UpdateTenacity();
|
||||||
|
UpdateTenacityList.clear();
|
||||||
|
context.Repeat(10s);
|
||||||
|
});
|
||||||
|
|
||||||
if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE))
|
if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE))
|
||||||
ChatHandler(nullptr).SendWorldText(BATTLEFIELD_WG_WORLD_START_MESSAGE);
|
ChatHandler(nullptr).SendWorldText(BATTLEFIELD_WG_WORLD_START_MESSAGE);
|
||||||
|
|||||||
@@ -449,8 +449,6 @@ protected:
|
|||||||
GuidUnorderedSet UpdateTenacityList;
|
GuidUnorderedSet UpdateTenacityList;
|
||||||
|
|
||||||
int32 TenacityStack;
|
int32 TenacityStack;
|
||||||
uint32 TenacityUpdateTimer;
|
|
||||||
uint32 SaveTimer;
|
|
||||||
|
|
||||||
ObjectGuid TitansRelic;
|
ObjectGuid TitansRelic;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -591,6 +591,8 @@ void WorldConfig::BuildConfigCache()
|
|||||||
SetConfigValue<uint32>(CONFIG_WINTERGRASP_NOBATTLETIME, "Wintergrasp.NoBattleTimer", 150);
|
SetConfigValue<uint32>(CONFIG_WINTERGRASP_NOBATTLETIME, "Wintergrasp.NoBattleTimer", 150);
|
||||||
SetConfigValue<uint32>(CONFIG_WINTERGRASP_RESTART_AFTER_CRASH, "Wintergrasp.CrashRestartTimer", 10);
|
SetConfigValue<uint32>(CONFIG_WINTERGRASP_RESTART_AFTER_CRASH, "Wintergrasp.CrashRestartTimer", 10);
|
||||||
|
|
||||||
|
SetConfigValue<uint32>(CONFIG_WINTERGRASP_SKIP_BATTLE_SESSION_COUNT, "Wintergrasp.SkipBattleSessionCount", 3500);
|
||||||
|
|
||||||
SetConfigValue<uint32>(CONFIG_BIRTHDAY_TIME, "BirthdayTime", 1222964635);
|
SetConfigValue<uint32>(CONFIG_BIRTHDAY_TIME, "BirthdayTime", 1222964635);
|
||||||
SetConfigValue<bool>(CONFIG_MINIGOB_MANABONK, "Minigob.Manabonk.Enable", true);
|
SetConfigValue<bool>(CONFIG_MINIGOB_MANABONK, "Minigob.Manabonk.Enable", true);
|
||||||
|
|
||||||
|
|||||||
@@ -327,6 +327,7 @@ enum ServerConfigs
|
|||||||
CONFIG_WINTERGRASP_BATTLETIME,
|
CONFIG_WINTERGRASP_BATTLETIME,
|
||||||
CONFIG_WINTERGRASP_NOBATTLETIME,
|
CONFIG_WINTERGRASP_NOBATTLETIME,
|
||||||
CONFIG_WINTERGRASP_RESTART_AFTER_CRASH,
|
CONFIG_WINTERGRASP_RESTART_AFTER_CRASH,
|
||||||
|
CONFIG_WINTERGRASP_SKIP_BATTLE_SESSION_COUNT,
|
||||||
CONFIG_PACKET_SPOOF_BANMODE,
|
CONFIG_PACKET_SPOOF_BANMODE,
|
||||||
CONFIG_PACKET_SPOOF_BANDURATION,
|
CONFIG_PACKET_SPOOF_BANDURATION,
|
||||||
CONFIG_WARDEN_CLIENT_RESPONSE_DELAY,
|
CONFIG_WARDEN_CLIENT_RESPONSE_DELAY,
|
||||||
|
|||||||
Reference in New Issue
Block a user