[7254] Cleanups and batter checking in homebind/bgEntryPoint code.
* Load homebind data early in Player::LoadFromDB and use instead initital race points
in cases need some safe point if current coordinate broken by some reason.
* Store BG entry point in to WorldLocation and simplify calls.
* Set bg entry point at GM teleports to battleground for correct
auto-recall position at battleground end.
Author: VladimirMangos
--HG--
branch : trunk
This commit is contained in:
@@ -870,9 +870,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
|
||||
plr->SetBGTeam(0);
|
||||
|
||||
if(Transport)
|
||||
{
|
||||
plr->TeleportTo(plr->GetBattleGroundEntryPointMap(), plr->GetBattleGroundEntryPointX(), plr->GetBattleGroundEntryPointY(), plr->GetBattleGroundEntryPointZ(), plr->GetBattleGroundEntryPointO());
|
||||
}
|
||||
plr->TeleportTo(plr->GetBattleGroundEntryPoint());
|
||||
|
||||
// Log
|
||||
sLog.outDetail("BATTLEGROUND: Removed player %s from BattleGround.", plr->GetName());
|
||||
|
||||
@@ -464,7 +464,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
|
||||
// bg->AddPlayer(_player,team);
|
||||
sLog.outDebug("Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.",_player->GetName(),_player->GetGUIDLow(),bg->GetInstanceID(),bg->GetTypeID(),bgQueueTypeId);
|
||||
break;
|
||||
case 0: // leave queue
|
||||
case 0: // leave queue
|
||||
queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);
|
||||
/*
|
||||
if player leaves rated arena match before match start, it is counted as he played but he lost
|
||||
|
||||
@@ -784,6 +784,8 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
|
||||
// all's well, set bg id
|
||||
// when porting out from the bg, it will be reset to 0
|
||||
chr->SetBattleGroundId(m_session->GetPlayer()->GetBattleGroundId());
|
||||
// remember current position as entry point for return at bg end teleportation
|
||||
chr->SetBattleGroundEntryPoint(chr->GetMapId(),chr->GetPositionX(),chr->GetPositionY(),chr->GetPositionZ(),chr->GetOrientation());
|
||||
}
|
||||
else if(pMap->IsDungeon())
|
||||
{
|
||||
@@ -900,6 +902,8 @@ bool ChatHandler::HandleGonameCommand(const char* args)
|
||||
// all's well, set bg id
|
||||
// when porting out from the bg, it will be reset to 0
|
||||
_player->SetBattleGroundId(chr->GetBattleGroundId());
|
||||
// remember current position as entry point for return at bg end teleportation
|
||||
_player->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());
|
||||
}
|
||||
else if(cMap->IsDungeon() && cMap->Instanceable())
|
||||
{
|
||||
|
||||
+8
-6
@@ -2147,12 +2147,14 @@ void BattleGroundMap::UnloadAll(bool pForce)
|
||||
{
|
||||
while(HavePlayers())
|
||||
{
|
||||
Player * plr = m_mapRefManager.getFirst()->getSource();
|
||||
if(plr) (plr)->TeleportTo(plr->m_homebindMapId, plr->m_homebindX, plr->m_homebindY, plr->m_homebindZ, plr->GetOrientation());
|
||||
// TeleportTo removes the player from this map (if the map exists) -> calls BattleGroundMap::Remove -> invalidates the iterator.
|
||||
// just in case, remove the player from the list explicitly here as well to prevent a possible infinite loop
|
||||
// note that this remove is not needed if the code works well in other places
|
||||
plr->GetMapRef().unlink();
|
||||
if(Player * plr = m_mapRefManager.getFirst()->getSource())
|
||||
{
|
||||
plr->TeleportTo(plr->GetBattleGroundEntryPoint());
|
||||
// TeleportTo removes the player from this map (if the map exists) -> calls BattleGroundMap::Remove -> invalidates the iterator.
|
||||
// just in case, remove the player from the list explicitly here as well to prevent a possible infinite loop
|
||||
// note that this remove is not needed if the code works well in other places
|
||||
plr->GetMapRef().unlink();
|
||||
}
|
||||
}
|
||||
|
||||
Map::UnloadAll(pForce);
|
||||
|
||||
@@ -96,6 +96,11 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit
|
||||
return IsValidMAP(mapid) && Trinity::IsValidMapCoord(x,y,z,o);
|
||||
}
|
||||
|
||||
static bool IsValidMapCoord(WorldLocation const& loc)
|
||||
{
|
||||
return IsValidMapCoord(loc.mapid,loc.x,loc.y,loc.z,loc.o);
|
||||
}
|
||||
|
||||
void DoDelayedMovesAndRemoves();
|
||||
|
||||
void LoadTransports();
|
||||
|
||||
+36
-41
@@ -14479,16 +14479,13 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
|
||||
m_class = fields[5].GetUInt8();
|
||||
|
||||
PlayerInfo const *info = objmgr.GetPlayerInfo(m_race, m_class);
|
||||
if(!info)
|
||||
{
|
||||
sLog.outError("Player have incorrect race/class pair. Can't be loaded.");
|
||||
delete result;
|
||||
// load home bind and check in same time class/race pair, it used later for restore broken positions
|
||||
if(!_LoadHomeBind(holder->GetResult(PLAYER_LOGIN_QUERY_LOADHOMEBIND)))
|
||||
return false;
|
||||
}
|
||||
|
||||
InitPrimaryProffesions(); // to max set before any spell loaded
|
||||
|
||||
// init saved position, and fix it later if problematic
|
||||
uint32 transGUID = fields[24].GetUInt32();
|
||||
Relocate(fields[6].GetFloat(),fields[7].GetFloat(),fields[8].GetFloat(),fields[10].GetFloat());
|
||||
SetMapId(fields[9].GetUInt32());
|
||||
@@ -14525,9 +14522,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
if(!IsPositionValid())
|
||||
{
|
||||
sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
||||
|
||||
SetMapId(info->mapId);
|
||||
Relocate(info->positionX,info->positionY,info->positionZ,0.0f);
|
||||
RelocateToHomebind();
|
||||
|
||||
transGUID = 0;
|
||||
|
||||
@@ -14537,10 +14532,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
m_movementInfo.t_o = 0.0f;
|
||||
}
|
||||
|
||||
if(!_LoadHomeBind(holder->GetResult(PLAYER_LOGIN_QUERY_LOADHOMEBIND)))
|
||||
return false;
|
||||
|
||||
// load the player's map here if it's not already loaded
|
||||
/*// load the player's map here if it's not already loaded
|
||||
Map *map = GetMap();
|
||||
if (!map)
|
||||
{
|
||||
@@ -14574,22 +14566,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
// since the player may not be bound to the map yet, make sure subsequent
|
||||
// getmap calls won't create new maps
|
||||
SetInstanceId(map->GetInstanceId());
|
||||
|
||||
// if the player is in an instance and it has been reset in the meantime teleport him to the entrance
|
||||
if(GetInstanceId() && !sInstanceSaveManager.GetInstanceSave(GetInstanceId()))
|
||||
{
|
||||
AreaTrigger const* at = objmgr.GetMapEntranceTrigger(GetMapId());
|
||||
if(at)
|
||||
Relocate(at->target_X, at->target_Y, at->target_Z, at->target_Orientation);
|
||||
else
|
||||
sLog.outError("Player %s(GUID: %u) logged in to a reset instance (map: %u) and there is no aretrigger leading to this map. Thus he can't be ported back to the entrance. This _might_ be an exploit attempt.", GetName(), GetGUIDLow(), GetMapId());
|
||||
}
|
||||
|
||||
SaveRecallPosition();
|
||||
}*/
|
||||
|
||||
if (transGUID != 0)
|
||||
{
|
||||
@@ -14608,8 +14585,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
guid,GetPositionX()+m_movementInfo.t_x,GetPositionY()+m_movementInfo.t_y,
|
||||
GetPositionZ()+m_movementInfo.t_z,GetOrientation()+m_movementInfo.t_o);
|
||||
|
||||
SetMapId(info->mapId);
|
||||
Relocate(info->positionX,info->positionY,info->positionZ,0.0f);
|
||||
RelocateToHomebind();
|
||||
|
||||
m_movementInfo.t_x = 0.0f;
|
||||
m_movementInfo.t_y = 0.0f;
|
||||
@@ -14638,8 +14614,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
sLog.outError("ERROR: Player (guidlow %d) have invalid transport guid (%u). Teleport to default race/class locations.",
|
||||
guid,transGUID);
|
||||
|
||||
SetMapId(info->mapId);
|
||||
Relocate(info->positionX,info->positionY,info->positionZ,0.0f);
|
||||
RelocateToHomebind();
|
||||
|
||||
m_movementInfo.t_x = 0.0f;
|
||||
m_movementInfo.t_y = 0.0f;
|
||||
@@ -14650,6 +14625,26 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
}
|
||||
}
|
||||
|
||||
// NOW player must have valid map
|
||||
// load the player's map here if it's not already loaded
|
||||
Map *map = GetMap();
|
||||
|
||||
// since the player may not be bound to the map yet, make sure subsequent
|
||||
// getmap calls won't create new maps
|
||||
SetInstanceId(map->GetInstanceId());
|
||||
|
||||
// if the player is in an instance and it has been reset in the meantime teleport him to the entrance
|
||||
if(GetInstanceId() && !sInstanceSaveManager.GetInstanceSave(GetInstanceId()))
|
||||
{
|
||||
AreaTrigger const* at = objmgr.GetMapEntranceTrigger(GetMapId());
|
||||
if(at)
|
||||
Relocate(at->target_X, at->target_Y, at->target_Z, at->target_Orientation);
|
||||
else
|
||||
sLog.outError("Player %s(GUID: %u) logged in to a reset instance (map: %u) and there is no aretrigger leading to this map. Thus he can't be ported back to the entrance. This _might_ be an exploit attempt.", GetName(), GetGUIDLow(), GetMapId());
|
||||
}
|
||||
|
||||
SaveRecallPosition();
|
||||
|
||||
time_t now = time(NULL);
|
||||
time_t logoutTime = time_t(fields[16].GetUInt64());
|
||||
|
||||
@@ -14797,9 +14792,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
|
||||
m_social = sSocialMgr.LoadFromDB(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSOCIALLIST), GetGUIDLow());
|
||||
|
||||
//if(!_LoadHomeBind(holder->GetResult(PLAYER_LOGIN_QUERY_LOADHOMEBIND)))
|
||||
// return false;
|
||||
|
||||
// check PLAYER_CHOSEN_TITLE compatibility with PLAYER__FIELD_KNOWN_TITLES
|
||||
// note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded
|
||||
if(uint32 curTitle = GetUInt32Value(PLAYER_CHOSEN_TITLE))
|
||||
@@ -14819,8 +14811,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
if(!nodeEntry) // don't know taxi start node, to homebind
|
||||
{
|
||||
sLog.outError("Character %u have wrong data in taxi destination list, teleport to homebind.",GetGUIDLow());
|
||||
SetMapId(m_homebindMapId);
|
||||
Relocate( m_homebindX, m_homebindY, m_homebindZ,0.0f);
|
||||
RelocateToHomebind();
|
||||
SaveRecallPosition(); // save as recall also to prevent recall and fall from sky
|
||||
}
|
||||
else // have start node, to it
|
||||
@@ -15847,6 +15838,13 @@ void Player::ConvertInstancesToGroup(Player *player, Group *group, uint64 player
|
||||
|
||||
bool Player::_LoadHomeBind(QueryResult *result)
|
||||
{
|
||||
PlayerInfo const *info = objmgr.GetPlayerInfo(getRace(), getClass());
|
||||
if(!info)
|
||||
{
|
||||
sLog.outError("Player have incorrect race/class pair. Can't be loaded.");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
//QueryResult *result = CharacterDatabase.PQuery("SELECT map,zone,position_x,position_y,position_z FROM character_homebind WHERE guid = '%u'", GUID_LOPART(playerGuid));
|
||||
if (result)
|
||||
@@ -15871,9 +15869,6 @@ bool Player::_LoadHomeBind(QueryResult *result)
|
||||
|
||||
if(!ok)
|
||||
{
|
||||
PlayerInfo const *info = objmgr.GetPlayerInfo(getRace(), getClass());
|
||||
if(!info) return false;
|
||||
|
||||
m_homebindMapId = info->mapId;
|
||||
m_homebindZoneId = info->zoneId;
|
||||
m_homebindX = info->positionX;
|
||||
|
||||
+4
-15
@@ -1939,18 +1939,10 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
uint32 GetBattleGroundEntryPointMap() const { return m_bgEntryPointMap; }
|
||||
float GetBattleGroundEntryPointX() const { return m_bgEntryPointX; }
|
||||
float GetBattleGroundEntryPointY() const { return m_bgEntryPointY; }
|
||||
float GetBattleGroundEntryPointZ() const { return m_bgEntryPointZ; }
|
||||
float GetBattleGroundEntryPointO() const { return m_bgEntryPointO; }
|
||||
WorldLocation const& GetBattleGroundEntryPoint() const { return m_bgEntryPoint; }
|
||||
void SetBattleGroundEntryPoint(uint32 Map, float PosX, float PosY, float PosZ, float PosO )
|
||||
{
|
||||
m_bgEntryPointMap = Map;
|
||||
m_bgEntryPointX = PosX;
|
||||
m_bgEntryPointY = PosY;
|
||||
m_bgEntryPointZ = PosZ;
|
||||
m_bgEntryPointO = PosO;
|
||||
m_bgEntryPoint = WorldLocation(Map,PosX,PosY,PosZ,PosO);
|
||||
}
|
||||
|
||||
void SetBGTeam(uint32 team) { m_bgTeam = team; }
|
||||
@@ -2075,6 +2067,7 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
float m_homebindX;
|
||||
float m_homebindY;
|
||||
float m_homebindZ;
|
||||
void RelocateToHomebind() { SetMapId(m_homebindMapId); Relocate(m_homebindX,m_homebindY,m_homebindZ); }
|
||||
|
||||
// currently visible objects at player client
|
||||
typedef std::set<uint64> ClientGUIDs;
|
||||
@@ -2188,11 +2181,7 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
uint32 invitedToInstance;
|
||||
};
|
||||
BgBattleGroundQueueID_Rec m_bgBattleGroundQueueID[PLAYER_MAX_BATTLEGROUND_QUEUES];
|
||||
uint32 m_bgEntryPointMap;
|
||||
float m_bgEntryPointX;
|
||||
float m_bgEntryPointY;
|
||||
float m_bgEntryPointZ;
|
||||
float m_bgEntryPointO;
|
||||
WorldLocation m_bgEntryPoint;
|
||||
|
||||
std::set<uint32> m_bgAfkReporter;
|
||||
uint8 m_bgAfkReportedCount;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "7253"
|
||||
#define REVISION_NR "7254"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
||||
Reference in New Issue
Block a user