mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 10:37:03 +00:00
[7487] Avoid attempt use InstanceSave data for non-dungeons.
Also check map existance and correctness at instance data loading. Removed unused and totally bugged InstanceMap::GetResetTime.
This commit is contained in:
parent
b3490d3b74
commit
a7fd57cc74
6 changed files with 85 additions and 70 deletions
|
|
@ -511,7 +511,7 @@ bool ChatHandler::HandleGonameCommand(const char* args)
|
|||
// 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())
|
||||
else if(cMap->IsDungeon())
|
||||
{
|
||||
// we have to go to instance, and can go to player only if:
|
||||
// 1) we are in his group (either as leader or as member)
|
||||
|
|
|
|||
133
src/game/Map.cpp
133
src/game/Map.cpp
|
|
@ -2137,76 +2137,80 @@ bool InstanceMap::Add(Player *player)
|
|||
if(!CanEnter(player))
|
||||
return false;
|
||||
|
||||
// get or create an instance save for the map
|
||||
InstanceSave *mapSave = sInstanceSaveManager.GetInstanceSave(GetInstanceId());
|
||||
if(!mapSave)
|
||||
// Dungeon only code
|
||||
if(IsDungeon())
|
||||
{
|
||||
sLog.outDetail("InstanceMap::Add: creating instance save for map %d spawnmode %d with instance id %d", GetId(), GetSpawnMode(), GetInstanceId());
|
||||
mapSave = sInstanceSaveManager.AddInstanceSave(GetId(), GetInstanceId(), GetSpawnMode(), 0, true);
|
||||
}
|
||||
|
||||
// check for existing instance binds
|
||||
InstancePlayerBind *playerBind = player->GetBoundInstance(GetId(), GetSpawnMode());
|
||||
if(playerBind && playerBind->perm)
|
||||
{
|
||||
// cannot enter other instances if bound permanently
|
||||
if(playerBind->save != mapSave)
|
||||
// get or create an instance save for the map
|
||||
InstanceSave *mapSave = sInstanceSaveManager.GetInstanceSave(GetInstanceId());
|
||||
if(!mapSave)
|
||||
{
|
||||
sLog.outError("InstanceMap::Add: player %s(%d) is permanently bound to instance %d,%d,%d,%d,%d,%d but he is being put in instance %d,%d,%d,%d,%d,%d", player->GetName(), player->GetGUIDLow(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset());
|
||||
assert(false);
|
||||
sLog.outDetail("InstanceMap::Add: creating instance save for map %d spawnmode %d with instance id %d", GetId(), GetSpawnMode(), GetInstanceId());
|
||||
mapSave = sInstanceSaveManager.AddInstanceSave(GetId(), GetInstanceId(), GetSpawnMode(), 0, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Group *pGroup = player->GetGroup();
|
||||
if(pGroup)
|
||||
|
||||
// check for existing instance binds
|
||||
InstancePlayerBind *playerBind = player->GetBoundInstance(GetId(), GetSpawnMode());
|
||||
if(playerBind && playerBind->perm)
|
||||
{
|
||||
// solo saves should be reset when entering a group
|
||||
InstanceGroupBind *groupBind = pGroup->GetBoundInstance(GetId(), GetSpawnMode());
|
||||
if(playerBind)
|
||||
// cannot enter other instances if bound permanently
|
||||
if(playerBind->save != mapSave)
|
||||
{
|
||||
sLog.outError("InstanceMap::Add: player %s(%d) is being put in instance %d,%d,%d,%d,%d,%d but he is in group %d and is bound to instance %d,%d,%d,%d,%d,%d!", player->GetName(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), GUID_LOPART(pGroup->GetLeaderGUID()), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
|
||||
if(groupBind) sLog.outError("InstanceMap::Add: the group is bound to instance %d,%d,%d,%d,%d,%d", groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset());
|
||||
sLog.outError("InstanceMap::Add: player %s(%d) is permanently bound to instance %d,%d,%d,%d,%d,%d but he is being put in instance %d,%d,%d,%d,%d,%d", player->GetName(), player->GetGUIDLow(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset());
|
||||
assert(false);
|
||||
}
|
||||
// bind to the group or keep using the group save
|
||||
if(!groupBind)
|
||||
pGroup->BindToInstance(mapSave, false);
|
||||
else
|
||||
{
|
||||
// cannot jump to a different instance without resetting it
|
||||
if(groupBind->save != mapSave)
|
||||
{
|
||||
sLog.outError("InstanceMap::Add: player %s(%d) is being put in instance %d,%d,%d but he is in group %d which is bound to instance %d,%d,%d!", player->GetName(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), GUID_LOPART(pGroup->GetLeaderGUID()), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty());
|
||||
if(mapSave)
|
||||
sLog.outError("MapSave players: %d, group count: %d", mapSave->GetPlayerCount(), mapSave->GetGroupCount());
|
||||
else
|
||||
sLog.outError("MapSave NULL");
|
||||
if(groupBind->save)
|
||||
sLog.outError("GroupBind save players: %d, group count: %d", groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount());
|
||||
else
|
||||
sLog.outError("GroupBind save NULL");
|
||||
assert(false);
|
||||
}
|
||||
// if the group/leader is permanently bound to the instance
|
||||
// players also become permanently bound when they enter
|
||||
if(groupBind->perm)
|
||||
{
|
||||
WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4);
|
||||
data << uint32(0);
|
||||
player->GetSession()->SendPacket(&data);
|
||||
player->BindToInstance(mapSave, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// set up a solo bind or continue using it
|
||||
if(!playerBind)
|
||||
player->BindToInstance(mapSave, false);
|
||||
Group *pGroup = player->GetGroup();
|
||||
if(pGroup)
|
||||
{
|
||||
// solo saves should be reset when entering a group
|
||||
InstanceGroupBind *groupBind = pGroup->GetBoundInstance(GetId(), GetSpawnMode());
|
||||
if(playerBind)
|
||||
{
|
||||
sLog.outError("InstanceMap::Add: player %s(%d) is being put in instance %d,%d,%d,%d,%d,%d but he is in group %d and is bound to instance %d,%d,%d,%d,%d,%d!", player->GetName(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), GUID_LOPART(pGroup->GetLeaderGUID()), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
|
||||
if(groupBind) sLog.outError("InstanceMap::Add: the group is bound to instance %d,%d,%d,%d,%d,%d", groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset());
|
||||
assert(false);
|
||||
}
|
||||
// bind to the group or keep using the group save
|
||||
if(!groupBind)
|
||||
pGroup->BindToInstance(mapSave, false);
|
||||
else
|
||||
{
|
||||
// cannot jump to a different instance without resetting it
|
||||
if(groupBind->save != mapSave)
|
||||
{
|
||||
sLog.outError("InstanceMap::Add: player %s(%d) is being put in instance %d,%d,%d but he is in group %d which is bound to instance %d,%d,%d!", player->GetName(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), GUID_LOPART(pGroup->GetLeaderGUID()), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty());
|
||||
if(mapSave)
|
||||
sLog.outError("MapSave players: %d, group count: %d", mapSave->GetPlayerCount(), mapSave->GetGroupCount());
|
||||
else
|
||||
sLog.outError("MapSave NULL");
|
||||
if(groupBind->save)
|
||||
sLog.outError("GroupBind save players: %d, group count: %d", groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount());
|
||||
else
|
||||
sLog.outError("GroupBind save NULL");
|
||||
assert(false);
|
||||
}
|
||||
// if the group/leader is permanently bound to the instance
|
||||
// players also become permanently bound when they enter
|
||||
if(groupBind->perm)
|
||||
{
|
||||
WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4);
|
||||
data << uint32(0);
|
||||
player->GetSession()->SendPacket(&data);
|
||||
player->BindToInstance(mapSave, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
// cannot jump to a different instance without resetting it
|
||||
assert(playerBind->save == mapSave);
|
||||
{
|
||||
// set up a solo bind or continue using it
|
||||
if(!playerBind)
|
||||
player->BindToInstance(mapSave, false);
|
||||
else
|
||||
// cannot jump to a different instance without resetting it
|
||||
assert(playerBind->save == mapSave);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2327,6 +2331,9 @@ bool InstanceMap::Reset(uint8 method)
|
|||
|
||||
void InstanceMap::PermBindAllPlayers(Player *player)
|
||||
{
|
||||
if(!IsDungeon())
|
||||
return;
|
||||
|
||||
InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId());
|
||||
if(!save)
|
||||
{
|
||||
|
|
@ -2356,12 +2363,6 @@ void InstanceMap::PermBindAllPlayers(Player *player)
|
|||
}
|
||||
}
|
||||
|
||||
time_t InstanceMap::GetResetTime()
|
||||
{
|
||||
InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId());
|
||||
return save ? save->GetDifficulty() : DIFFICULTY_NORMAL;
|
||||
}
|
||||
|
||||
void InstanceMap::UnloadAll(bool pForce)
|
||||
{
|
||||
if(HavePlayers())
|
||||
|
|
@ -2391,7 +2392,7 @@ void InstanceMap::SetResetSchedule(bool on)
|
|||
// only for normal instances
|
||||
// the reset time is only scheduled when there are no payers inside
|
||||
// it is assumed that the reset time will rarely (if ever) change while the reset is scheduled
|
||||
if(!HavePlayers() && !IsRaid() && !IsHeroic())
|
||||
if(IsDungeon() && !HavePlayers() && !IsRaid() && !IsHeroic())
|
||||
{
|
||||
InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId());
|
||||
if(!save) sLog.outError("InstanceMap::SetResetSchedule: cannot turn schedule %s, no save available for instance %d of %d", on ? "on" : "off", GetInstanceId(), GetId());
|
||||
|
|
|
|||
|
|
@ -530,7 +530,6 @@ class MANGOS_DLL_SPEC InstanceMap : public Map
|
|||
uint32 GetScriptId() { return i_script_id; }
|
||||
InstanceData* GetInstanceData() { return i_data; }
|
||||
void PermBindAllPlayers(Player *player);
|
||||
time_t GetResetTime();
|
||||
void UnloadAll(bool pForce);
|
||||
bool CanEnter(Player* player);
|
||||
void SendResetWarnings(uint32 timeLeft) const;
|
||||
|
|
|
|||
|
|
@ -2709,7 +2709,14 @@ void ObjectMgr::LoadGroups()
|
|||
}
|
||||
}
|
||||
|
||||
InstanceSave *save = sInstanceSaveManager.AddInstanceSave(fields[1].GetUInt32(), fields[2].GetUInt32(), fields[4].GetUInt8(), (time_t)fields[5].GetUInt64(), (fields[6].GetUInt32() == 0), true);
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(fields[1].GetUInt32());
|
||||
if(!mapEntry || !mapEntry->IsDungeon())
|
||||
{
|
||||
sLog.outErrorDb("Incorrect entry in group_instance table : no dungeon map %d", fields[1].GetUInt32());
|
||||
continue;
|
||||
}
|
||||
|
||||
InstanceSave *save = sInstanceSaveManager.AddInstanceSave(mapEntry->MapID, fields[2].GetUInt32(), fields[4].GetUInt8(), (time_t)fields[5].GetUInt64(), (fields[6].GetUInt32() == 0), true);
|
||||
group->BindToInstance(save, fields[3].GetBool(), true);
|
||||
}while( result->NextRow() );
|
||||
delete result;
|
||||
|
|
|
|||
|
|
@ -15469,6 +15469,14 @@ void Player::_LoadBoundInstances(QueryResult *result)
|
|||
// so the value read from the DB may be wrong here but only if the InstanceSave is loaded
|
||||
// and in that case it is not used
|
||||
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(mapId);
|
||||
if(!mapEntry || !mapEntry->IsDungeon())
|
||||
{
|
||||
sLog.outError("_LoadBoundInstances: player %s(%d) has bind to not existed or not dungeon map %d", GetName(), GetGUIDLow(), mapId);
|
||||
CharacterDatabase.PExecute("DELETE FROM character_instance WHERE guid = '%d' AND instance = '%d'", GetGUIDLow(), instanceId);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!perm && group)
|
||||
{
|
||||
sLog.outError("_LoadBoundInstances: player %s(%d) is in group %d but has a non-permanent character bind to map %d,%d,%d", GetName(), GetGUIDLow(), GUID_LOPART(group->GetLeaderGUID()), mapId, instanceId, difficulty);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "7486"
|
||||
#define REVISION_NR "7487"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue