Skip to content

Commit

Permalink
Fix raid reset exploit.
Browse files Browse the repository at this point in the history
  • Loading branch information
ratkosrb committed Dec 27, 2023
1 parent fc0d6cf commit dd79947
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 2 deletions.
5 changes: 4 additions & 1 deletion src/game/Handlers/GroupHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,11 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recv_data)
return;
}

if (GetPlayer()->GetMapId() > 1 && GetPlayer()->GetInstanceId() && player->GetInstanceId() && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId())
// Prevent inviting player to group who is in a different instance of the same map.
if (GetPlayer()->GetMapId() > 1 && GetPlayer()->GetInstanceId() && player->GetInstanceId() &&
GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId())
return;

// Just ignore us
if (player->GetSocial()->HasIgnore(GetPlayer()->GetObjectGuid()))
{
Expand Down
5 changes: 5 additions & 0 deletions src/game/Handlers/MovementHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ void WorldSession::HandleMoveWorldportAckOpcode()

if (mEntry->IsRaid())
{
// Cancel any group invites on teleport to dungeon to prevent raid reset exploits.
// We already prevent inviting player who is in different instance of same map.
// This makes sure you cant bypass that by inviting player first but not accepting until inside.
GetPlayer()->UninviteFromGroup();

if (time_t timeReset = sMapPersistentStateMgr.GetScheduler().GetResetTimeFor(mEntry->id))
{
uint32 timeleft = uint32(timeReset - time(nullptr));
Expand Down
10 changes: 9 additions & 1 deletion src/game/Maps/Map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2283,7 +2283,7 @@ bool DungeonMap::Reset(InstanceResetMethod method)
}
else
{
if (method == INSTANCE_RESET_GLOBAL)
if (method == INSTANCE_RESET_GLOBAL || method == INSTANCE_RESET_GROUP_JOIN)
{
// set the homebind timer for players inside (1 minute)
for (const auto& itr : m_mapRefManager)
Expand Down Expand Up @@ -2313,11 +2313,19 @@ void DungeonMap::PermBindAllPlayers(Player* player)
for (const auto& itr : m_mapRefManager)
{
Player* plr = itr.getSource();

// players inside an instance cannot be bound to other instances
// some players may already be permanently bound, in this case nothing happens
InstancePlayerBind *bind = plr->GetBoundInstance(GetId());
if (!bind || !bind->perm)
{
if (m_resetAfterUnload)
{
sLog.Player(plr->GetSession(), LOG_BASIC, LOG_LVL_ERROR, "Attempt to permanently save player to raid (map %u, instance %u) scheduled for reset on unload and already deleted from DB!", GetId(), GetInstanceId());
plr->TeleportToHomebind();
continue;
}

plr->BindToInstance(GetPersistanceState(), true);
WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4);
data << uint32(0);
Expand Down

0 comments on commit dd79947

Please sign in to comment.