diff options
author | zartech22 <kevin.plestan@outlook.fr> | 2019-06-22 19:23:42 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2021-12-11 23:12:27 +0100 |
commit | 1c3c59d7fac0abb02cc1fb433338737ea119831d (patch) | |
tree | a4a53f1e1ae95a7ce185c0a7951fad2e13ccaff0 /src | |
parent | 799fba7fd12f34968d5ea34aaaed1a14bc20ae3f (diff) |
Core/Instance : Fix instance resetting exploit (#23263)
* Push offline players out of instance
Push offline players out of instance when reseting dungeon with a raid mode group
* Add SQL request to character
Add a SQL request to update the position of a player in a specified map
* Teleport to graveyard instead
(cherry picked from commit 678e0e606aa38e18fd361c33bc91833fdae76735)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.cpp | 1 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.h | 1 | ||||
-rw-r--r-- | src/server/game/Groups/Group.cpp | 38 |
3 files changed, 40 insertions, 0 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index ea1d8841e58..bc6cffcee26 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -539,6 +539,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_DEL_CHARACTER_SOCIAL, "DELETE FROM character_social WHERE guid = ? AND friend = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHARACTER_SOCIAL_NOTE, "UPDATE character_social SET note = ? WHERE guid = ? AND friend = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHARACTER_POSITION, "UPDATE characters SET position_x = ?, position_y = ?, position_z = ?, orientation = ?, map = ?, zone = ?, trans_x = 0, trans_y = 0, trans_z = 0, transguid = 0, taxi_path = '', cinematic = 1 WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_CHARACTER_POSITION_BY_MAPID, "UPDATE characters SET position_x = ?, position_y = ?, position_z = ?, orientation = ?, map = ?, zone = ?, trans_x = 0, trans_y = 0, trans_z = 0, transguid = 0, taxi_path = '', cinematic = 1 WHERE guid = ? AND map = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_AURA_FROZEN, "SELECT characters.name, character_aura.remainTime FROM characters LEFT JOIN character_aura ON (characters.guid = character_aura.guid) WHERE character_aura.spell = 9454", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_CHARACTER_ONLINE, "SELECT name, account, map, zone FROM characters WHERE online > 0", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_CHAR_DEL_INFO_BY_GUID, "SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL AND guid = ?", CONNECTION_BOTH); diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h index 4ed8d70df1e..460a6ef1886 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.h +++ b/src/server/database/Database/Implementation/CharacterDatabase.h @@ -423,6 +423,7 @@ enum CharacterDatabaseStatements : uint32 CHAR_DEL_CHARACTER_SOCIAL, CHAR_UPD_CHARACTER_SOCIAL_NOTE, CHAR_UPD_CHARACTER_POSITION, + CHAR_UPD_CHARACTER_POSITION_BY_MAPID, CHAR_INS_LFG_DATA, CHAR_DEL_LFG_DATA, diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index bdb6b05253e..f8cf13c1112 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -35,6 +35,7 @@ #include "ObjectMgr.h" #include "PartyPackets.h" #include "Pet.h" +#include "PhasingHandler.h" #include "Player.h" #include "Random.h" #include "UpdateData.h" @@ -2150,7 +2151,44 @@ void Group::ResetInstances(uint8 method, bool isRaid, bool isLegacy, Player* Sen { // do not reset the instance, just unbind if others are permanently bound to it if (isEmpty && instanceSave->CanReset()) + { + if (map && this->isRaidGroup() && map->IsDungeon() && SendMsgTo) + { + AreaTriggerStruct const* instanceEntrance = sObjectMgr->GetGoBackTrigger(map->GetId()); + + if (!instanceEntrance) + TC_LOG_DEBUG("root", "Instance entrance not found for maps %u", map->GetId()); + else + { + WorldSafeLocsEntry const* graveyardLocation = sObjectMgr->GetClosestGraveyard( + WorldLocation(instanceEntrance->target_mapId, instanceEntrance->target_X, instanceEntrance->target_Y, instanceEntrance->target_Z), + SendMsgTo->GetTeam(), nullptr); + uint32 const zoneId = sMapMgr->GetZoneId(PhasingHandler::GetEmptyPhaseShift(), graveyardLocation->Loc.GetMapId(), + graveyardLocation->Loc.GetPositionX(), graveyardLocation->Loc.GetPositionY(), graveyardLocation->Loc.GetPositionZ()); + + for (MemberSlot const& member : GetMemberSlots()) + { + if (!ObjectAccessor::FindConnectedPlayer(member.guid)) + { + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHARACTER_POSITION_BY_MAPID); + + stmt->setFloat(0, graveyardLocation->Loc.GetPositionX()); + stmt->setFloat(1, graveyardLocation->Loc.GetPositionY()); + stmt->setFloat(2, graveyardLocation->Loc.GetPositionZ()); + stmt->setFloat(3, instanceEntrance->target_Orientation); + stmt->setUInt32(4, graveyardLocation->Loc.GetMapId()); + stmt->setUInt32(5, zoneId); + stmt->setUInt64(6, member.guid.GetCounter()); + stmt->setUInt32(7, map->GetId()); + + CharacterDatabase.Execute(stmt); + } + } + } + } + instanceSave->DeleteFromDB(); + } else { CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_INSTANCE_BY_INSTANCE); |