Add stricter regulations for instances (login-checks and support for sending unbound player to parent-instance / homebind if not matching criterias)
Patch by Elron103 - closes issue #1323. --HG-- branch : trunk
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
AZEROTH
|
||||
Shadowfang Keep Entrance, Stormwind Stockades Entrance, DeadMines Entrance, Uldaman Entrance, Gnomeregan Entrance,
|
||||
Altar of Atal'Hakkar Entrance, Scarlet Monastery - Graveyard (Entrance), Blackrock Spire - Searing Gorge Instance (Inside),
|
||||
Blackrock Mountain - Searing Gorge Instance?, Scholomance Entrance, Zul'Gurub Entrance, Stratholme - Eastern Plaguelands Instance,
|
||||
Karazhan, Main (Entrance)
|
||||
*/
|
||||
UPDATE `instance_template` SET `parent` = 0 WHERE `map` IN (33, 34, 36, 70, 90, 109, 189, 229, 230, 289, 309, 329, 532);
|
||||
|
||||
/*
|
||||
KALIMDOR
|
||||
The Barrens - Wailing Caverns, Razorfen Kraul Entrance, Blackphantom Deeps Entrance, Razorfen Downs Entrance,
|
||||
Zul'Farrak Entrance, Onyxia's Lair Entrance, Caverns Of Time, Black Morass (Entrance), Maraudon,
|
||||
Ragefire Chasm - Ogrimmar Instance, Dire Maul, Ruins Of Ahn'Qiraj (Outside), Ahn'Qiraj Temple (Outside),
|
||||
Battle Of Mount Hyjal, Alliance Base (Entrance), Culling of Stratholme (entrance), Caverns Of Time, Old Hillsbrad Foothills (Entrance)
|
||||
*/
|
||||
UPDATE `instance_template` SET `parent` = 1 WHERE `map` IN (43, 47, 48, 129, 209, 249, 269, 349, 389, 429, 509, 531, 534, 560, 595);
|
||||
|
||||
/*
|
||||
OUTLAND
|
||||
The Shattered Halls (Entrance), The Blood Furnace (Entrance), Hellfire Ramparts (Entrance), Magtheridon's Lair (Entrance),
|
||||
The Steamvault (Entrance), The Underbog (Entrance), The Slave Pens (Entrance), Serpentshrine Cavern (Entrance),
|
||||
The Eye (Entrance), The Arcatraz (Entrance), The Botanica (Entrance), The Mechanar (Entrance),
|
||||
Shadow Labyrinth (Entrance), Sethekk Halls (Entrance), Mana Tombs (Entrance), Auchenai Crypts (Entrance),
|
||||
Black Temple (Entrance), Gruul's Lair (Entrance),
|
||||
Zul'Aman (Entrance), Sunwell Plateau (Entrance), Magisters' Terrace (Entrance),
|
||||
*/
|
||||
UPDATE `instance_template` SET `parent` = 530 WHERE `map` IN (540, 542, 543, 544, 545, 546, 547, 548, 550, 552, 553, 554, 555, 556, 557, 558, 564, 565, 568, 580, 585);
|
||||
|
||||
/*
|
||||
NORTHREND
|
||||
Chamber of Aspects, Obsidian Sanctum (entrance), Utgarde Keep (entrance), Utgarde Pinnacle (entrance),
|
||||
The Nexus (entrance), The Oculus (entrance), Naxxramas (to frostwyrm lair), Violet Hold (entrance),
|
||||
Gundrak (entrance north), Ulduar, Halls of Lightning (entrance), Ulduar, Halls of Stone (entrance),
|
||||
Azjol-Nerub (entrance), Ahn'Kahet (entrance), Drak'Tharon Keep (entrance), The Eye of Eternity (entrance),
|
||||
Vault of Archavon (Entrance), Ulduar Raid entrance, Trial of the Champion, Trial of the Crusader,
|
||||
*/
|
||||
UPDATE `instance_template` SET `parent` = 571 WHERE `map` IN (615, 574, 575, 576, 578, 533, 608, 604, 602, 599, 601, 619, 600, 616, 624, 603, 650, 649);
|
||||
|
||||
-- The Molten Bridge
|
||||
UPDATE `instance_template` SET `parent` = 230 WHERE `map` = 409;
|
||||
|
||||
-- Blackwing Lair - Blackrock Mountain - Eastern Kingdoms
|
||||
UPDATE `instance_template` SET `parent` = 229 WHERE `map` = 469;
|
||||
|
||||
|
||||
/*
|
||||
NOT ASSIGNED, SET TO DBC VALUE
|
||||
*/
|
||||
|
||||
/*
|
||||
DBC VALUE 0
|
||||
Warsong Gulch, Alterac Valley, Arathi Basin, Eye of the Storm, Nagrand Arena, Blades Edge Arena, Ruins of Lordaeron,
|
||||
Isle of Conquest, Strand of the Ancients
|
||||
*/
|
||||
UPDATE `instance_template` SET `parent` = 0 WHERE `map` IN (489, 529, 566, 559, 562, 572, 628, 607);
|
||||
/*
|
||||
DBC VALUE 4294967295
|
||||
Alterac Valley
|
||||
*/
|
||||
UPDATE `instance_template` SET `parent` = 4294967295 WHERE `map` IN (30);
|
||||
@@ -708,7 +708,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
|
||||
}
|
||||
}
|
||||
|
||||
if (!pCurrChar->GetMap()->Add(pCurrChar))
|
||||
if (!pCurrChar->GetMap()->Add(pCurrChar) || !pCurrChar->CheckInstanceLoginValid())
|
||||
{
|
||||
AreaTrigger const* at = objmgr.GetGoBackTrigger(pCurrChar->GetMapId());
|
||||
if (at)
|
||||
|
||||
@@ -1796,14 +1796,7 @@ void Group::UnbindInstance(uint32 mapid, uint8 difficulty, bool unload)
|
||||
void Group::_homebindIfInstance(Player *player)
|
||||
{
|
||||
if (player && !player->isGameMaster() && sMapStore.LookupEntry(player->GetMapId())->IsDungeon())
|
||||
{
|
||||
// leaving the group in an instance, the homebind timer is started
|
||||
// unless the player is permanently saved to the instance
|
||||
InstanceSave *save = sInstanceSaveManager.GetInstanceSave(player->GetInstanceId());
|
||||
InstancePlayerBind *playerBind = save ? player->GetBoundInstance(save->GetMapId(), save->GetDifficulty()) : NULL;
|
||||
if (!playerBind || !playerBind->perm)
|
||||
player->m_InstanceValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Group::BroadcastGroupUpdate(void)
|
||||
|
||||
@@ -157,7 +157,7 @@ Map* MapManager::FindMap(uint32 mapid, uint32 instanceId) const
|
||||
return ((MapInstanced*)map)->FindMap(instanceId);
|
||||
}
|
||||
|
||||
bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)
|
||||
bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck)
|
||||
{
|
||||
const MapEntry *entry = sMapStore.LookupEntry(mapid);
|
||||
if (!entry)
|
||||
@@ -263,7 +263,7 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)
|
||||
int8 maxPlayers = mapDiff ? mapDiff->maxPlayers : 0;
|
||||
if (maxPlayers != -1) //-1: unlimited access
|
||||
{
|
||||
if (boundedMap->GetPlayersCountExceptGMs() >= maxPlayers)
|
||||
if (loginCheck ? boundedMap->GetPlayersCountExceptGMs() > maxPlayers : boundedMap->GetPlayersCountExceptGMs() >= maxPlayers)
|
||||
{
|
||||
sLog.outDebug("MAP: Player '%s' can't enter instance '%s' because it's full.", player->GetName(), mapName);
|
||||
player->SendTransferAborted(mapid, TRANSFER_ABORT_MAX_PLAYERS);
|
||||
|
||||
@@ -118,7 +118,7 @@ class MapManager : public Trinity::Singleton<MapManager, Trinity::ClassLevelLock
|
||||
typedef std::map<uint32, TransportSet> TransportMap;
|
||||
TransportMap m_TransportsByMap;
|
||||
|
||||
bool CanPlayerEnter(uint32 mapid, Player* player);
|
||||
bool CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck = false);
|
||||
void RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y);
|
||||
uint32 GenerateInstanceId() { return ++i_MaxInstanceId; }
|
||||
void InitMaxInstanceId();
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
#include "CreatureAI.h"
|
||||
#include "DBCEnums.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "MapManager.h"
|
||||
#include "InstanceData.h"
|
||||
|
||||
void WorldSession::HandleRepopRequestOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
@@ -915,6 +917,25 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
|
||||
if (!GetPlayer()->Satisfy(objmgr.GetAccessRequirement(at->access_id), at->target_mapId, true))
|
||||
return;
|
||||
|
||||
// check if player can enter instance : instance not full, and raid instance not in encounter fight
|
||||
if (Map * newMap = MapManager::Instance().CreateMap(at->target_mapId, GetPlayer(), 0))
|
||||
{
|
||||
if (newMap && newMap->IsDungeon() && ((InstanceMap*)newMap)->GetInstanceData() && ((InstanceMap*)newMap)->GetMapDifficulty())
|
||||
{
|
||||
if (newMap->GetPlayersCountExceptGMs() >= ((InstanceMap*)newMap)->GetMapDifficulty()->maxPlayers)
|
||||
{
|
||||
GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_MAX_PLAYERS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (newMap->IsRaid() && ((InstanceMap*)newMap)->GetInstanceData()->IsEncounterInProgress())
|
||||
{
|
||||
GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_ZONE_IN_COMBAT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,TELE_TO_NOT_LEAVE_TRANSPORT);
|
||||
}
|
||||
|
||||
|
||||
+18
-3
@@ -5899,15 +5899,30 @@ void ObjectMgr::LoadAccessRequirements()
|
||||
}
|
||||
|
||||
/*
|
||||
* Searches for the areatrigger which teleports players out of the given map
|
||||
* Searches for the areatrigger which teleports players out of the given map with instance_template.parent field support
|
||||
*/
|
||||
AreaTrigger const* ObjectMgr::GetGoBackTrigger(uint32 Map) const
|
||||
{
|
||||
bool useParentDbValue = false;
|
||||
uint32 parentId = 0;
|
||||
const MapEntry *mapEntry = sMapStore.LookupEntry(Map);
|
||||
if (!mapEntry || mapEntry->entrance_map < 0) return NULL;
|
||||
if (!mapEntry || mapEntry->entrance_map < 0)
|
||||
return NULL;
|
||||
|
||||
if (mapEntry->IsDungeon())
|
||||
{
|
||||
const InstanceTemplate *iTemplate = objmgr.GetInstanceTemplate(Map);
|
||||
|
||||
if (!iTemplate)
|
||||
return NULL;
|
||||
|
||||
parentId = iTemplate->parent;
|
||||
useParentDbValue = true;
|
||||
}
|
||||
|
||||
uint32 entrance_map = uint32(mapEntry->entrance_map);
|
||||
for (AreaTriggerMap::const_iterator itr = mAreaTriggers.begin(); itr != mAreaTriggers.end(); ++itr)
|
||||
if (itr->second.target_mapId == entrance_map)
|
||||
if ((!useParentDbValue && itr->second.target_mapId == entrance_map) || (useParentDbValue && itr->second.target_mapId == parentId))
|
||||
{
|
||||
AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(itr->first);
|
||||
if (atEntry && atEntry->mapid == Map)
|
||||
|
||||
+26
-1
@@ -1826,7 +1826,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||
|
||||
// Check enter rights before map getting to avoid creating instance copy for player
|
||||
// this check not dependent from map instance copy and same for all instance copies of selected map
|
||||
if (!MapManager::Instance().CanPlayerEnter(mapid, this))
|
||||
if (!MapManager::Instance().CanPlayerEnter(mapid, this, false))
|
||||
return false;
|
||||
|
||||
// If the map is not created, assume it is possible to enter it.
|
||||
@@ -17347,6 +17347,31 @@ bool Player::Satisfy(AccessRequirement const *ar, uint32 target_map, bool report
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Player::CheckInstanceLoginValid()
|
||||
{
|
||||
if (!GetMap())
|
||||
return false;
|
||||
|
||||
if (!GetMap()->IsDungeon() || isGameMaster())
|
||||
return true;
|
||||
|
||||
if (GetMap()->IsRaid())
|
||||
{
|
||||
// cannot be in raid instance without a group
|
||||
if (!GetGroup())
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// cannot be in normal instance without a group and more players than 1 in instance
|
||||
if (!GetGroup() && GetMap()->GetPlayersCountExceptGMs() > 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
// do checks for satisfy accessreqs, instance full, encounter in progress (raid), perm bind group != perm bind player
|
||||
return MapManager::Instance().CanPlayerEnter(GetMap()->GetId(), this, true);
|
||||
}
|
||||
|
||||
bool Player::_LoadHomeBind(QueryResult_AutoPtr result)
|
||||
{
|
||||
PlayerInfo const *info = objmgr.GetPlayerInfo(getRace(), getClass());
|
||||
|
||||
@@ -2266,6 +2266,7 @@ class Player : public Unit, public GridObject<Player>
|
||||
void SendSavedInstances();
|
||||
static void ConvertInstancesToGroup(Player *player, Group *group = NULL, uint64 player_guid = 0);
|
||||
bool Satisfy(AccessRequirement const*, uint32 target_map, bool report = false);
|
||||
bool CheckInstanceLoginValid();
|
||||
|
||||
// last used pet number (for BG's)
|
||||
uint32 GetLastPetNumber() const { return m_lastpetnumber; }
|
||||
|
||||
Reference in New Issue
Block a user