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:
click
2010-05-04 18:25:30 +02:00
parent 51d0c07c90
commit 029e480454
9 changed files with 132 additions and 16 deletions
@@ -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);
+1 -1
View File
@@ -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)
-7
View File
@@ -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)
+2 -2
View File
@@ -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);
+1 -1
View File
@@ -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();
+21
View File
@@ -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
View File
@@ -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
View File
@@ -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());
+1
View File
@@ -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; }