mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Instance: stop updating the instance resettimes based on creature respawns
- Rather update normal instance reset time to 2 hours after last creature kill
- This fixes yet another integer overflow due to the possibility of having time_t max showing up
- Also change respawntime and resettime fields to bigint on respawn/instance related tables
- Start using prepared statements on the InstanceSaveMgr
(cherry picked from commit 4c593f12ca)
This commit is contained in:
@@ -1895,7 +1895,7 @@ DROP TABLE IF EXISTS `creature_respawn`;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `creature_respawn` (
|
||||
`guid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier',
|
||||
`respawnTime` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`respawnTime` bigint(20) unsigned NOT NULL DEFAULT '0',
|
||||
`mapId` smallint(10) unsigned NOT NULL DEFAULT '0',
|
||||
`instanceId` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Instance Identifier',
|
||||
PRIMARY KEY (`guid`,`instanceId`),
|
||||
@@ -1969,7 +1969,7 @@ DROP TABLE IF EXISTS `gameobject_respawn`;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `gameobject_respawn` (
|
||||
`guid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier',
|
||||
`respawnTime` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`respawnTime` bigint(20) unsigned NOT NULL DEFAULT '0',
|
||||
`mapId` smallint(10) unsigned NOT NULL DEFAULT '0',
|
||||
`instanceId` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Instance Identifier',
|
||||
PRIMARY KEY (`guid`,`instanceId`),
|
||||
@@ -2616,7 +2616,7 @@ DROP TABLE IF EXISTS `instance`;
|
||||
CREATE TABLE `instance` (
|
||||
`id` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`map` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`resettime` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`resettime` bigint(20) unsigned NOT NULL DEFAULT '0',
|
||||
`difficulty` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`completedEncounters` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`data` tinytext NOT NULL,
|
||||
@@ -2647,7 +2647,7 @@ DROP TABLE IF EXISTS `instance_reset`;
|
||||
CREATE TABLE `instance_reset` (
|
||||
`mapid` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`difficulty` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`resettime` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`resettime` bigint(20) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`mapid`,`difficulty`),
|
||||
KEY `difficulty` (`difficulty`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
@@ -3773,7 +3773,8 @@ INSERT INTO `updates` VALUES
|
||||
('2020_04_20_00_characters.sql','977B5E0C894E0A7E80B2A9626F17CA636A69BD22','RELEASED','2020-04-20 19:08:18',0),
|
||||
('2020_04_24_00_characters.sql','85E2E0395A9457A53D73A9E0A7BB39B7E4C429BF','RELEASED','2020-04-24 22:04:59',0),
|
||||
('2020_04_25_00_characters_2017_04_03_00_characters.sql','00FA3EFADAF807AC96619A3FE47216E21C3FCB19','RELEASED','2020-04-25 00:00:00',0),
|
||||
('2020_04_26_00_characters_2017_04_12_00_characters.sql','86AA94DA9B1EA283101100886C10F648C0CE6494','RELEASED','2020-04-26 00:00:00',0);
|
||||
('2020_04_26_00_characters_2017_04_12_00_characters.sql','86AA94DA9B1EA283101100886C10F648C0CE6494','RELEASED','2020-04-26 00:00:00',0),
|
||||
('2020_04_26_01_characters_2017_04_12_01_characters.sql','5A8A1215E3A2356722F52CD7A64BBE03D21FBEA3','RELEASED','2020-04-26 00:00:00',0);
|
||||
|
||||
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE `creature_respawn` CHANGE `respawnTime` `respawnTime` bigint(20) unsigned NOT NULL DEFAULT '0';
|
||||
ALTER TABLE `gameobject_respawn` CHANGE `respawnTime` `respawnTime` bigint(20) unsigned NOT NULL DEFAULT '0';
|
||||
ALTER TABLE `instance` CHANGE `resettime` `resettime` bigint(20) unsigned NOT NULL DEFAULT '0';
|
||||
ALTER TABLE `instance_reset` CHANGE `resettime` `resettime` bigint(20) unsigned NOT NULL DEFAULT '0';
|
||||
@@ -429,7 +429,6 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_REP_CREATURE_RESPAWN, "REPLACE INTO creature_respawn (guid, respawnTime, mapId, instanceId) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_CREATURE_RESPAWN, "DELETE FROM creature_respawn WHERE guid = ? AND mapId = ? AND instanceId = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE, "DELETE FROM creature_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_MAX_CREATURE_RESPAWNS, "SELECT MAX(respawnTime), instanceId FROM creature_respawn WHERE instanceId > 0 GROUP BY instanceId", CONNECTION_SYNCH);
|
||||
|
||||
// Gameobject respawn
|
||||
PrepareStatement(CHAR_SEL_GO_RESPAWNS, "SELECT guid, respawnTime FROM gameobject_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_SYNCH);
|
||||
@@ -511,7 +510,9 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_DEL_GROUP_INSTANCE_BY_GUID, "DELETE FROM group_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_REP_GROUP_INSTANCE, "REPLACE INTO group_instance (guid, instance, permanent) VALUES (?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_INSTANCE_RESETTIME, "UPDATE instance SET resettime = ? WHERE id = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_GLOBAL_INSTANCE_RESETTIME, "UPDATE instance_reset SET resettime = ? WHERE mapid = ? AND difficulty = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_GLOBAL_INSTANCE_RESETTIME, "INSERT INTO instance_reset (mapid, difficulty, resettime) VALUES (?, ?, ?)", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_DEL_GLOBAL_INSTANCE_RESETTIME, "DELETE FROM instance_reset WHERE mapid = ? AND difficulty = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_UPD_GLOBAL_INSTANCE_RESETTIME, "UPDATE instance_reset SET resettime = ? WHERE mapid = ? AND difficulty = ?", CONNECTION_BOTH);
|
||||
PrepareStatement(CHAR_UPD_CHAR_ONLINE, "UPDATE characters SET online = 1 WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN, "UPDATE characters SET name = ?, at_login = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_WORLDSTATE, "UPDATE worldstates SET value = ? WHERE entry = ?", CONNECTION_ASYNC);
|
||||
|
||||
@@ -340,7 +340,6 @@ enum CharacterDatabaseStatements : uint32
|
||||
CHAR_REP_CREATURE_RESPAWN,
|
||||
CHAR_DEL_CREATURE_RESPAWN,
|
||||
CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE,
|
||||
CHAR_SEL_MAX_CREATURE_RESPAWNS,
|
||||
|
||||
CHAR_SEL_GO_RESPAWNS,
|
||||
CHAR_REP_GO_RESPAWN,
|
||||
@@ -400,6 +399,8 @@ enum CharacterDatabaseStatements : uint32
|
||||
CHAR_DEL_GROUP_INSTANCE_BY_GUID,
|
||||
CHAR_REP_GROUP_INSTANCE,
|
||||
CHAR_UPD_INSTANCE_RESETTIME,
|
||||
CHAR_INS_GLOBAL_INSTANCE_RESETTIME,
|
||||
CHAR_DEL_GLOBAL_INSTANCE_RESETTIME,
|
||||
CHAR_UPD_GLOBAL_INSTANCE_RESETTIME,
|
||||
CHAR_UPD_CHAR_ONLINE,
|
||||
CHAR_UPD_CHAR_NAME_AT_LOGIN,
|
||||
|
||||
@@ -19819,7 +19819,8 @@ void Player::_LoadBoundInstances(PreparedQueryResult result)
|
||||
|
||||
Group* group = GetGroup();
|
||||
|
||||
//QueryResult* result = CharacterDatabase.PQuery("SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
// 0 1 2 3 4 5 6
|
||||
// SELECT id, permanent, map, difficulty, extendState, resettime, entranceId FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = ?
|
||||
if (result)
|
||||
{
|
||||
do
|
||||
@@ -19832,7 +19833,7 @@ void Player::_LoadBoundInstances(PreparedQueryResult result)
|
||||
uint8 difficulty = fields[3].GetUInt8();
|
||||
BindExtensionState extendState = BindExtensionState(fields[4].GetUInt8());
|
||||
|
||||
time_t resetTime = time_t(fields[5].GetUInt32());
|
||||
time_t resetTime = time_t(fields[5].GetUInt64());
|
||||
// the resettime for normal instances is only saved when the InstanceSave is unloaded
|
||||
// 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
|
||||
|
||||
@@ -11513,7 +11513,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss)
|
||||
{
|
||||
// the reset time is set but not added to the scheduler
|
||||
// until the players leave the instance
|
||||
time_t resettime = creature->GetRespawnTimeEx() + 2 * HOUR;
|
||||
time_t resettime = GameTime::GetGameTime() + 2 * HOUR;
|
||||
if (InstanceSave* save = sInstanceSaveMgr->GetInstanceSave(creature->GetInstanceId()))
|
||||
if (save->GetResetTime() < resettime)
|
||||
save->SetResetTime(resettime);
|
||||
|
||||
@@ -168,7 +168,7 @@ void InstanceSaveManager::RemoveInstanceSave(uint32 InstanceId)
|
||||
{
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_INSTANCE_RESETTIME);
|
||||
|
||||
stmt->setUInt32(0, uint32(resettime));
|
||||
stmt->setUInt64(0, uint64(resettime));
|
||||
stmt->setUInt32(1, InstanceId);
|
||||
|
||||
CharacterDatabase.Execute(stmt);
|
||||
@@ -222,7 +222,7 @@ void InstanceSave::SaveToDB()
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_INSTANCE_SAVE);
|
||||
stmt->setUInt32(0, m_instanceid);
|
||||
stmt->setUInt16(1, GetMapId());
|
||||
stmt->setUInt32(2, uint32(GetResetTimeForDB()));
|
||||
stmt->setUInt64(2, uint64(GetResetTimeForDB()));
|
||||
stmt->setUInt8(3, uint8(GetDifficultyID()));
|
||||
stmt->setUInt32(4, completedEncounters);
|
||||
stmt->setString(5, data);
|
||||
@@ -329,8 +329,7 @@ void InstanceSaveManager::LoadResetTimes()
|
||||
typedef std::pair<ResetTimeMapDiffInstances::const_iterator, ResetTimeMapDiffInstances::const_iterator> ResetTimeMapDiffInstancesBounds;
|
||||
ResetTimeMapDiffInstances mapDiffResetInstances;
|
||||
|
||||
QueryResult result = CharacterDatabase.Query("SELECT id, map, difficulty, resettime FROM instance ORDER BY id ASC");
|
||||
if (result)
|
||||
if (QueryResult result = CharacterDatabase.Query("SELECT id, map, difficulty, resettime FROM instance ORDER BY id ASC"))
|
||||
{
|
||||
do
|
||||
{
|
||||
@@ -346,7 +345,7 @@ void InstanceSaveManager::LoadResetTimes()
|
||||
// Mark instance id as being used
|
||||
sMapMgr->RegisterInstanceId(instanceId);
|
||||
|
||||
if (time_t resettime = time_t(fields[3].GetUInt32()))
|
||||
if (time_t resettime = time_t(fields[3].GetUInt64()))
|
||||
{
|
||||
uint32 mapid = fields[1].GetUInt16();
|
||||
uint32 difficulty = fields[2].GetUInt8();
|
||||
@@ -357,24 +356,6 @@ void InstanceSaveManager::LoadResetTimes()
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
// update reset time for normal instances with the max creature respawn time + X hours
|
||||
if (PreparedQueryResult result2 = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAX_CREATURE_RESPAWNS)))
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = result2->Fetch();
|
||||
uint32 instance = fields[1].GetUInt32();
|
||||
time_t resettime = time_t(fields[0].GetUInt32() + 2 * HOUR);
|
||||
InstResetTimeMapDiffType::iterator itr = instResetTime.find(instance);
|
||||
if (itr != instResetTime.end() && itr->second.second != resettime)
|
||||
{
|
||||
CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '" UI64FMTD "' WHERE id = '%u'", uint64(resettime), instance);
|
||||
itr->second.second = resettime;
|
||||
}
|
||||
}
|
||||
while (result2->NextRow());
|
||||
}
|
||||
|
||||
// schedule the reset times
|
||||
for (InstResetTimeMapDiffType::iterator itr = instResetTime.begin(); itr != instResetTime.end(); ++itr)
|
||||
if (itr->second.second > now)
|
||||
@@ -383,28 +364,37 @@ void InstanceSaveManager::LoadResetTimes()
|
||||
|
||||
// load the global respawn times for raid/heroic instances
|
||||
uint32 diff = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR;
|
||||
result = CharacterDatabase.Query("SELECT mapid, difficulty, resettime FROM instance_reset");
|
||||
if (result)
|
||||
if (QueryResult result = CharacterDatabase.Query("SELECT mapid, difficulty, resettime FROM instance_reset"))
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint32 mapid = fields[0].GetUInt16();
|
||||
Difficulty difficulty = Difficulty(fields[1].GetUInt8());
|
||||
uint64 oldresettime = fields[2].GetUInt32();
|
||||
uint64 oldresettime = fields[2].GetUInt64();
|
||||
|
||||
MapDifficultyEntry const* mapDiff = sDB2Manager.GetMapDifficultyData(mapid, difficulty);
|
||||
if (!mapDiff)
|
||||
{
|
||||
TC_LOG_ERROR("misc", "InstanceSaveManager::LoadResetTimes: invalid mapid(%u)/difficulty(%u) pair in instance_reset!", mapid, uint32(difficulty));
|
||||
CharacterDatabase.DirectPExecute("DELETE FROM instance_reset WHERE mapid = '%u' AND difficulty = '%u'", mapid, uint32(difficulty));
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GLOBAL_INSTANCE_RESETTIME);
|
||||
stmt->setUInt16(0, uint16(mapid));
|
||||
stmt->setUInt8(1, uint8(difficulty));
|
||||
CharacterDatabase.DirectExecute(stmt);
|
||||
continue;
|
||||
}
|
||||
|
||||
// update the reset time if the hour in the configs changes
|
||||
uint64 newresettime = (oldresettime / DAY) * DAY + diff;
|
||||
if (oldresettime != newresettime)
|
||||
CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '%u' WHERE mapid = '%u' AND difficulty = '%u'", uint32(newresettime), mapid, uint32(difficulty));
|
||||
{
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GLOBAL_INSTANCE_RESETTIME);
|
||||
stmt->setUInt64(0, uint64(newresettime));
|
||||
stmt->setUInt16(1, uint16(mapid));
|
||||
stmt->setUInt8(2, uint8(difficulty));
|
||||
CharacterDatabase.DirectExecute(stmt);
|
||||
}
|
||||
|
||||
InitializeResetTimeFor(mapid, difficulty, newresettime);
|
||||
} while (result->NextRow());
|
||||
@@ -433,7 +423,12 @@ void InstanceSaveManager::LoadResetTimes()
|
||||
{
|
||||
// initialize the reset time
|
||||
t = today + period + diff;
|
||||
CharacterDatabase.DirectPExecute("INSERT INTO instance_reset VALUES ('%u', '%u', '%u')", mapid, uint32(difficulty), (uint32)t);
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GLOBAL_INSTANCE_RESETTIME);
|
||||
stmt->setUInt16(0, uint16(mapid));
|
||||
stmt->setUInt8(1, uint8(difficulty));
|
||||
stmt->setUInt64(2, uint64(t));
|
||||
CharacterDatabase.DirectExecute(stmt);
|
||||
}
|
||||
|
||||
if (t < now)
|
||||
@@ -442,7 +437,12 @@ void InstanceSaveManager::LoadResetTimes()
|
||||
// calculate the next reset time
|
||||
t = (t / DAY) * DAY;
|
||||
t += ((today - t) / period + 1) * period + diff;
|
||||
CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '" UI64FMTD "' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, uint32(difficulty));
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GLOBAL_INSTANCE_RESETTIME);
|
||||
stmt->setUInt64(0, uint64(t));
|
||||
stmt->setUInt16(1, uint16(mapid));
|
||||
stmt->setUInt8(2, uint8(difficulty));
|
||||
CharacterDatabase.DirectExecute(stmt);
|
||||
}
|
||||
|
||||
InitializeResetTimeFor(mapid, difficulty, t);
|
||||
@@ -702,7 +702,7 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, b
|
||||
// Update it in the DB
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GLOBAL_INSTANCE_RESETTIME);
|
||||
|
||||
stmt->setUInt32(0, next_reset);
|
||||
stmt->setUInt64(0, uint64(next_reset));
|
||||
stmt->setUInt16(1, uint16(mapid));
|
||||
stmt->setUInt8(2, uint8(difficulty));
|
||||
|
||||
|
||||
@@ -3982,7 +3982,7 @@ void Map::SaveCreatureRespawnTime(ObjectGuid::LowType dbGuid, time_t respawnTime
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CREATURE_RESPAWN);
|
||||
stmt->setUInt64(0, dbGuid);
|
||||
stmt->setUInt32(1, uint32(respawnTime));
|
||||
stmt->setUInt64(1, uint64(respawnTime));
|
||||
stmt->setUInt16(2, GetId());
|
||||
stmt->setUInt32(3, GetInstanceId());
|
||||
CharacterDatabase.Execute(stmt);
|
||||
@@ -4012,7 +4012,7 @@ void Map::SaveGORespawnTime(ObjectGuid::LowType dbGuid, time_t respawnTime)
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GO_RESPAWN);
|
||||
stmt->setUInt64(0, dbGuid);
|
||||
stmt->setUInt32(1, uint32(respawnTime));
|
||||
stmt->setUInt64(1, uint64(respawnTime));
|
||||
stmt->setUInt16(2, GetId());
|
||||
stmt->setUInt32(3, GetInstanceId());
|
||||
CharacterDatabase.Execute(stmt);
|
||||
@@ -4040,7 +4040,7 @@ void Map::LoadRespawnTimes()
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
ObjectGuid::LowType loguid = fields[0].GetUInt64();
|
||||
uint32 respawnTime = fields[1].GetUInt32();
|
||||
uint64 respawnTime = fields[1].GetUInt64();
|
||||
|
||||
_creatureRespawnTimes[loguid] = time_t(respawnTime);
|
||||
} while (result->NextRow());
|
||||
@@ -4055,7 +4055,7 @@ void Map::LoadRespawnTimes()
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
ObjectGuid::LowType loguid = fields[0].GetUInt64();
|
||||
uint32 respawnTime = fields[1].GetUInt32();
|
||||
uint64 respawnTime = fields[1].GetUInt64();
|
||||
|
||||
_goRespawnTimes[loguid] = time_t(respawnTime);
|
||||
} while (result->NextRow());
|
||||
|
||||
Reference in New Issue
Block a user