[7255] Allows saving characters in Battle Grounds.
* Now player can join to BG after logout during 5 minutes, if BG in progress.
* All players after server crash or restart should appear at the battlemaster
Author: GriffonHeart
--HG--
branch : trunk
This commit is contained in:
+8
-1
@@ -21,7 +21,7 @@
|
||||
|
||||
DROP TABLE IF EXISTS `character_db_version`;
|
||||
CREATE TABLE `character_db_version` (
|
||||
`required_7251_02_characters_character_spell` bit(1) default NULL
|
||||
`required_7255_01_characters_characters` bit(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
|
||||
|
||||
--
|
||||
@@ -285,6 +285,13 @@ CREATE TABLE `characters` (
|
||||
`taxi_path` text,
|
||||
`arena_pending_points` int(10) UNSIGNED NOT NULL default '0',
|
||||
`latency` int(11) unsigned NOT NULL default '0',
|
||||
`bgid` int(10) unsigned NOT NULL default '0',
|
||||
`bgteam` int(10) unsigned NOT NULL default '0',
|
||||
`bgmap` int(10) unsigned NOT NULL default '0',
|
||||
`bgx` float NOT NULL default '0',
|
||||
`bgy` float NOT NULL default '0',
|
||||
`bgz` float NOT NULL default '0',
|
||||
`bgo` float NOT NULL default '0',
|
||||
PRIMARY KEY (`guid`),
|
||||
KEY `idx_account` (`account`),
|
||||
KEY `idx_online` (`online`),
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
ALTER TABLE character_db_version CHANGE COLUMN required_7251_02_characters_character_spell required_7255_01_characters_characters bit;
|
||||
|
||||
ALTER TABLE `characters`
|
||||
ADD COLUMN `bgid` int(10) unsigned NOT NULL default '0' AFTER `latency`,
|
||||
ADD COLUMN `bgteam` int(10) unsigned NOT NULL default '0' AFTER `bgid`,
|
||||
ADD COLUMN `bgmap` int(10) unsigned NOT NULL default '0' AFTER `bgteam`,
|
||||
ADD COLUMN `bgx` float NOT NULL default '0' AFTER `bgmap`,
|
||||
ADD COLUMN `bgy` float NOT NULL default '0' AFTER `bgx`,
|
||||
ADD COLUMN `bgz` float NOT NULL default '0' AFTER `bgy`,
|
||||
ADD COLUMN `bgo` float NOT NULL default '0' AFTER `bgz`;
|
||||
|
||||
@@ -165,8 +165,6 @@ void BattleGround::Update(uint32 diff)
|
||||
m_RemovedPlayers.clear();
|
||||
}
|
||||
|
||||
// this code isn't efficient and its idea isn't implemented yet
|
||||
/* offline players are removed from battleground in worldsession::LogoutPlayer()
|
||||
// remove offline players from bg after ~5 minutes
|
||||
if(GetPlayersSize())
|
||||
{
|
||||
@@ -181,7 +179,7 @@ void BattleGround::Update(uint32 diff)
|
||||
if(itr->second.LastOnlineTime >= MAX_OFFLINE_TIME) // 5 minutes
|
||||
m_RemovedPlayers[itr->first] = 1; // add to remove list (BG)
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
m_LastResurrectTime += diff;
|
||||
if (m_LastResurrectTime >= RESURRECTION_INTERVAL)
|
||||
@@ -1535,6 +1533,31 @@ uint32 BattleGround::GetPlayerTeam(uint64 guid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool BattleGround::IsPlayerInBattleGround(uint64 guid)
|
||||
{
|
||||
std::map<uint64, BattleGroundPlayer>::const_iterator itr = m_Players.find(guid);
|
||||
if(itr!=m_Players.end())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void BattleGround::PlayerRelogin(Player* plr)
|
||||
{
|
||||
if(GetStatus() != STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
WorldPacket data;
|
||||
uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
|
||||
|
||||
BlockMovement(plr);
|
||||
|
||||
sBattleGroundMgr.BuildPvpLogDataPacket(&data, this);
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
uint32 BattleGround::GetAlivePlayersCountByTeam(uint32 Team) const
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
@@ -452,6 +452,8 @@ class BattleGround
|
||||
|
||||
// since arenas can be AvA or Hvh, we have to get the "temporary" team of a player
|
||||
uint32 GetPlayerTeam(uint64 guid);
|
||||
bool IsPlayerInBattleGround(uint64 guid);
|
||||
void PlayerRelogin(Player* plr);
|
||||
|
||||
void SetDeleteThis() {m_SetDeleteThis = true;}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ bool LoginQueryHolder::Initialize()
|
||||
|
||||
// NOTE: all fields in `characters` must be read to prevent lost character data at next save in case wrong DB structure.
|
||||
// !!! NOTE: including unused `zone`,`online`
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty, arena_pending_points FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty, arena_pending_points,bgid,bgteam,bgmap,bgx,bgy,bgz,bgo FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT leaderGuid FROM group_member WHERE memberGuid ='%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
|
||||
@@ -132,31 +132,23 @@ void WorldSession::HandleMoveWorldportAckOpcode()
|
||||
if(!mEntry->IsMountAllowed())
|
||||
_player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
|
||||
|
||||
// battleground state prepare
|
||||
// battleground state prepare (in case join to BG), at relogin/tele player not invited
|
||||
// only add to bg group and object, if the player was invited (else he entered through command)
|
||||
if(_player->InBattleGround() && _player->IsInvitedForBattleGroundInstance(_player->GetBattleGroundId()))
|
||||
if(_player->InBattleGround())
|
||||
{
|
||||
BattleGround *bg = _player->GetBattleGround();
|
||||
if(bg)
|
||||
// cleanup seting if outdated
|
||||
if(!mEntry->IsBattleGroundOrArena())
|
||||
{
|
||||
bg->AddPlayer(_player);
|
||||
if(bg->GetMapId() == _player->GetMapId()) // we teleported to bg
|
||||
{
|
||||
// get the team this way, because arenas might 'override' the teams.
|
||||
uint32 team = bg->GetPlayerTeam(_player->GetGUID());
|
||||
if(!team)
|
||||
team = _player->GetTeam();
|
||||
if(!bg->GetBgRaid(team)) // first player joined
|
||||
{
|
||||
Group *group = new Group;
|
||||
bg->SetBgRaid(team, group);
|
||||
group->Create(_player->GetGUIDLow(), _player->GetName());
|
||||
}
|
||||
else // raid already exist
|
||||
{
|
||||
bg->GetBgRaid(team)->AddMember(_player->GetGUID(), _player->GetName());
|
||||
}
|
||||
}
|
||||
// Do next only if found in battleground
|
||||
_player->SetBattleGroundId(0); // We're not in BG.
|
||||
// reset destination bg team
|
||||
_player->SetBGTeam(0);
|
||||
}
|
||||
// join to bg case
|
||||
else if(BattleGround *bg = _player->GetBattleGround())
|
||||
{
|
||||
if(_player->IsInvitedForBattleGroundInstance(_player->GetBattleGroundId()))
|
||||
bg->AddPlayer(_player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+95
-21
@@ -14405,8 +14405,8 @@ float Player::GetFloatValueFromDB(uint16 index, uint64 guid)
|
||||
|
||||
bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
{
|
||||
//// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [28] [29] 30 31 32 33
|
||||
//QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty, arena_pending_points FROM characters WHERE guid = '%u'", guid);
|
||||
//// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [28] [29] 30 31 32 33 34 35 36 37 38 39 40
|
||||
//QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty, arena_pending_points,bgid,bgteam,bgmap,bgx,bgy,bgz,bgo FROM characters WHERE guid = '%u'", guid);
|
||||
QueryResult *result = holder->GetResult(PLAYER_LOGIN_QUERY_LOADFROM);
|
||||
|
||||
if(!result)
|
||||
@@ -14568,6 +14568,51 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
}
|
||||
}*/
|
||||
|
||||
uint32 bgid = fields[34].GetUInt32();
|
||||
uint32 bgteam = fields[35].GetUInt32();
|
||||
|
||||
if(bgid) //saved in BattleGround
|
||||
{
|
||||
SetBattleGroundEntryPoint(fields[36].GetUInt32(),fields[37].GetFloat(),fields[38].GetFloat(),fields[39].GetFloat(),fields[40].GetFloat());
|
||||
|
||||
// check entry point and fix to homebind if need
|
||||
if(!MapManager::IsValidMapCoord(m_bgEntryPoint))
|
||||
SetBattleGroundEntryPoint(m_homebindMapId,m_homebindX,m_homebindY,m_homebindZ,0.0f);
|
||||
|
||||
BattleGround *currentBg = sBattleGroundMgr.GetBattleGround(bgid);
|
||||
|
||||
if(currentBg && currentBg->IsPlayerInBattleGround(GetGUID()))
|
||||
{
|
||||
uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(currentBg->GetTypeID(), currentBg->GetArenaType());
|
||||
uint32 queueSlot = AddBattleGroundQueueId(bgQueueTypeId);
|
||||
|
||||
SetBattleGroundId(currentBg->GetInstanceID());
|
||||
SetBGTeam(bgteam);
|
||||
|
||||
SetInviteForBattleGroundQueueType(bgQueueTypeId,currentBg->GetInstanceID());
|
||||
}
|
||||
else
|
||||
{
|
||||
Relocate(GetBattleGroundEntryPoint());
|
||||
//RemoveArenaAuras(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(GetMapId());
|
||||
// if server restart after player save in BG or area
|
||||
// player can have current coordinates in to BG/Arean map, fix this
|
||||
if(!mapEntry || mapEntry->IsBattleGroundOrArena())
|
||||
{
|
||||
// return to BG master
|
||||
SetMapId(fields[36].GetUInt32());
|
||||
Relocate(fields[37].GetFloat(),fields[38].GetFloat(),fields[39].GetFloat(),fields[40].GetFloat());
|
||||
// check entry point and fix to homebind if need
|
||||
if(!IsPositionValid())
|
||||
RelocateToHomebind();
|
||||
}
|
||||
}
|
||||
|
||||
if (transGUID != 0)
|
||||
{
|
||||
m_movementInfo.t_x = fields[20].GetFloat();
|
||||
@@ -15896,12 +15941,6 @@ void Player::SaveToDB()
|
||||
// first save/honor gain after midnight will also update the player's honor fields
|
||||
UpdateHonorFields();
|
||||
|
||||
// players aren't saved on battleground maps
|
||||
uint32 mapid = IsBeingTeleported() ? GetTeleportDest().mapid : GetMapId();
|
||||
const MapEntry * me = sMapStore.LookupEntry(mapid);
|
||||
if(!me || me->IsBattleGroundOrArena())
|
||||
return;
|
||||
|
||||
int is_save_resting = HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ? 1 : 0;
|
||||
//save, far from tavern/city
|
||||
//save, but in tavern/city
|
||||
@@ -15937,23 +15976,14 @@ void Player::SaveToDB()
|
||||
"taximask, online, cinematic, "
|
||||
"totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, "
|
||||
"trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, "
|
||||
"death_expire_time, taxi_path, arena_pending_points, latency) VALUES ("
|
||||
"death_expire_time, taxi_path, arena_pending_points, latency, bgid, bgteam, bgmap, bgx, bgy, bgz, bgo) VALUES ("
|
||||
<< GetGUIDLow() << ", "
|
||||
<< GetSession()->GetAccountId() << ", '"
|
||||
<< sql_name << "', "
|
||||
<< m_race << ", "
|
||||
<< m_class << ", ";
|
||||
|
||||
bool save_to_dest = false;
|
||||
if(IsBeingTeleported())
|
||||
{
|
||||
// don't save to battlegrounds or arenas
|
||||
const MapEntry *entry = sMapStore.LookupEntry(GetTeleportDest().mapid);
|
||||
if(entry && entry->map_type != MAP_BATTLEGROUND && entry->map_type != MAP_ARENA)
|
||||
save_to_dest = true;
|
||||
}
|
||||
|
||||
if(!save_to_dest)
|
||||
if(!IsBeingTeleported())
|
||||
{
|
||||
ss << GetMapId() << ", "
|
||||
<< (uint32)GetDifficulty() << ", "
|
||||
@@ -16036,9 +16066,19 @@ void Player::SaveToDB()
|
||||
ss << ", '";
|
||||
ss << m_taxi.SaveTaxiDestinationsToString();
|
||||
|
||||
ss << "', '0', '";
|
||||
ss << "', '0', ";
|
||||
ss << GetSession()->GetLatency();
|
||||
ss << "' )";
|
||||
ss << ", ";
|
||||
ss << GetBattleGroundId();
|
||||
ss << ", ";
|
||||
ss << GetBGTeam();
|
||||
ss << ", ";
|
||||
ss << m_bgEntryPoint.mapid << ", "
|
||||
<< finiteAlways(m_bgEntryPoint.x) << ", "
|
||||
<< finiteAlways(m_bgEntryPoint.y) << ", "
|
||||
<< finiteAlways(m_bgEntryPoint.z) << ", "
|
||||
<< finiteAlways(m_bgEntryPoint.o);
|
||||
ss << ")";
|
||||
|
||||
CharacterDatabase.Execute( ss.str().c_str() );
|
||||
|
||||
@@ -18632,6 +18672,40 @@ void Player::SendInitialPacketsAfterAddToMap()
|
||||
SendMessageToSet(&data,true);
|
||||
}
|
||||
|
||||
// setup BG group membership if need
|
||||
if(BattleGround* currentBg = GetBattleGround())
|
||||
{
|
||||
// call for invited (join) or listed (relogin) and avoid other cases (GM teleport)
|
||||
if (IsInvitedForBattleGroundInstance(GetBattleGroundId()) ||
|
||||
currentBg->IsPlayerInBattleGround(GetGUID()))
|
||||
{
|
||||
currentBg->PlayerRelogin(this);
|
||||
if(currentBg->GetMapId() == GetMapId()) // we teleported/login to/in bg
|
||||
{
|
||||
uint32 team = currentBg->GetPlayerTeam(GetGUID());
|
||||
if(!team)
|
||||
team = GetTeam();
|
||||
Group* group = currentBg->GetBgRaid(team);
|
||||
if(!group) // first player joined
|
||||
{
|
||||
group = new Group;
|
||||
currentBg->SetBgRaid(team, group);
|
||||
group->Create(GetGUIDLow(), GetName());
|
||||
}
|
||||
else // raid already exist
|
||||
{
|
||||
if(group->IsMember(GetGUID()))
|
||||
{
|
||||
uint8 subgroup = group->GetMemberGroup(GetGUID());
|
||||
SetGroup(group, subgroup);
|
||||
}
|
||||
else
|
||||
currentBg->GetBgRaid(team)->AddMember(GetGUID(), GetName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SendAurasForTarget(this);
|
||||
SendEnchantmentDurations(); // must be after add to map
|
||||
SendItemDurations(); // must be after add to map
|
||||
|
||||
@@ -314,10 +314,6 @@ void WorldSession::LogoutPlayer(bool Save)
|
||||
_player->RepopAtGraveyard();
|
||||
}
|
||||
|
||||
///- Remove player from battleground (teleport to entrance)
|
||||
if(_player->InBattleGround())
|
||||
_player->LeaveBattleground();
|
||||
|
||||
///- Teleport to home if the player is in an invalid instance
|
||||
if(!_player->m_InstanceValid && !_player->isGameMaster())
|
||||
_player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation());
|
||||
|
||||
@@ -474,6 +474,9 @@ void Master::clearOnlineAccounts()
|
||||
"AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = '%d')",realmID);
|
||||
|
||||
CharacterDatabase.Execute("UPDATE characters SET online = 0 WHERE online<>0");
|
||||
|
||||
// Battleground instance ids reset at server restart
|
||||
CharacterDatabase.Execute("UPDATE characters SET bgid = 0 WHERE bgid<>0");
|
||||
}
|
||||
|
||||
/// Handle termination signals
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "7254"
|
||||
#define REVISION_NR "7255"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
||||
Reference in New Issue
Block a user